C++ String

A string is very similar to a std::vector
The following code snippet has the std::string name with the value RainerGrimm. I use the STL algorithm std::find_if to get the upper letter and then extract my first and last name into the variables firstName and lastName. The expression name.begin()+1 shows, that strings support random access iterators:

#include <algorithm>
#include <string>

std::string name{"RainerGrimm"};
auto strIt= std::find_if(name.begin()+1, name.end(),
                       [](char c){ return std::isupper(c); });
if (strIt != name.end()){
 firstName= std::string(name.begin(), strIt);
 lastName= std::string(strIt, name.end());
}

for multi byte string you can use basic_string

typedef basic_string<char> string;
typedef basic_string<wchar_t> wstring;
typedef basic_string<char16_t> u16string;
typedef basic_string<char32_t> u32string;

create string

std::string defaultString;
std::string other{"123456789"};
std::string str1(other);                      // 123456789
std::string tmp(other);                       // 123456789
std::string str2(std::move(tmp));             // 123456789
std::string str3(other.begin(), other.end()); // 123456789
std::string str4(other, 2);                   // 3456789
std::string str5(other, 2, 5);                // 34567
std::string str6("123456789", 5);             // 12345
std::string str7(5, '1');                     // 11111
std::string str8({'1', '2', '3', '4', '5'});  // 12345
std::cout << str6.substr();                   // 12345
std::cout << str6.substr(1);                  // 2345
std::cout << str6.substr(1, 2);               // 23
MethodsDescription
str.empty()Checks if str has elements.
str.size(), str.length()Number of elements of the str.
str.capacity()Number of elements str can have without reallocation.
str.max_size()Number of elements str can maximal have.
str.resize(n)Increases str to n elements.
str.reserve(n)Reserve memory for a least n elements.
str.shrink_to_fit()Adjusts the capacity of the string to it’s size.
size and capacity
void showStringInfo(const std::string& s){
  std::cout << s << ": ";
  std::cout << s.size() << " ";
  std::cout << s.capacity() << " ";
  std::cout << s.max_size() << " ";
}

std::string str;
showStringInfo(str);  // "": 0 0 4611686018427387897

str +="12345";
showStringInfo(str);  // "12345": 5 5 4611686018427387897

str.resize(30);
showStringInfo(str);  // "12345": 30 30 4611686018427387897

str.reserve(1000);
showStringInfo(str);  // "12345": 30 1000 4611686018427387897

str.shrink_to_fit();
showStringInfo(str);  // "12345": 30 30 4611686018427387897

Elements Access

std::string str= {"0123456789"};
std::cout << str.front() << std::endl;           // 0
std::cout << str.back() << std::endl;            // 9
for (int i= 0; i <= 3; ++i){
  std::cout << "str[" << i << "]:" << str[i] << "; ";
} // str[0]: 0; str[1]: 1; str[2]: 2; str[3]: 3;

std::cout << str[10] << std::endl;               // undefined behaviour
try{
  str.at(10);
}
catch (const std::out_of_range& e){
  std::cerr << "Exception: " << e.what() << std::endl;
} // Exception: basic_string::at

std::cout << *(&str[0]+5) << std::endl;         // 5
std::cout << *(&str[5]) << std::endl;           // 5
std::cout << str[5] << std::endl;               // 5

search

str= {"dkeu84kf8k48kdj39kdj74945du942"};
std::string str2{"84"};

std::cout << str.find('8');                              // 4
std::cout << str.rfind('8');                             // 11
std::cout << str.find('8', 10);                          // 11
std::cout << str.find(str2);                             // 4
std::cout << str.rfind(str2);                            // 4
std::cout << str.find(str2, 10);                         // 18446744073709551615

str2="0123456789";

std::cout << str.find_first_of("678");                    // 4
std::cout << str.find_last_of("678");                     // 20
std::cout << str.find_first_of("678", 10);                // 11
std::cout << str.find_first_of(str2);                     // 4
std::cout << str.find_last_of(str2);                      // 29
std::cout << str.find_first_of(str2, 10);                 // 10
std::cout << str.find_first_not_of("678");                // 0
std::cout << str.find_last_not_of("678");                 // 29
std::cout << str.find_first_not_of("678", 10);            // 10
std::cout << str.find_first_not_of(str2);                 // 0
std::cout << str.find_last_not_of(str2);                  // 26
std::cout << str.find_first_not_of(str2, 10);             // 12
MethodsDescription
str= str2Assigns str2 to str.
str.assign(...)Assigns to stra new string.
str.swap(str2)Swaps str and str2.
str.pop_back()Removes the last character from str.
str.erase(...)Removes characters from str.
str.clear()Clears the str.
str.append(...)Appends characters to str.
str.push_back(s)Appends the character s to str.
str.insert(pos, ...)Inserts characters in str starting at pos.
str.replace(pos, len, ...)Replaces the len characters from str starting at pos
modifying functions
MethodDescription
std::to_string(val)Converts val into a std::string.
std::to_wstring(val)Converts val into a std::wstring.
std::stoi(str)Returns an int value.
std::stol(str)Returns a long value.
std::stoll(str)Returns a long long value.
std::stoul(str)Returns an unsigned long value.
std::stoull(str)Returns an unsigned long long value.
std::stof(str)Returns a float value.
std::stod(str)Returns a double value.
std::stold(str)Returns an long double value.
numeric converting

Regular Expression

typedef basic_regex<char> regex;
typedef basic_regex<wchar_t> wregex;

search

#include <regex>
...
using std::regex_constants::ECMAScript;
using std::regex_constants::icase;

std::string theQuestion="C++ or c++, that's the question.";
std::string regExprStr(R"(c\+\+)");

std::regex rgx(regExprStr);
std::smatch smatch;

if (std::regex_search(theQuestion, smatch, rgx)){
  std::cout << "case sensitive: " << smatch[0];       // c++
}

std::regex rgxIn(regExprStr, ECMAScript|icase);
if (std::regex_search(theQuestion, smatch, rgxIn)){
  std::cout << "case insensitive: " << smatch[0];     // C++
}
#include <regex>
...

// regular expression holder for time
std::regex crgx("([01]?[0-9]|2[0-3]):[0-5][0-9]");

// const char*
std::cmatch cmatch;

const char* ctime{"Now it is 23:10."};
if (std::regex_search(ctime, cmatch, crgx)){
  std::cout << ctime << std::endl;                   // Now it is 23:10.   
  std::cout << "Time: " << cmatch[0] << std::endl;   // Time: 23:10
}

// std::string
std::smatch smatch;

std::string stime{"Now it is 23:25."};
if (std::regex_search(stime, smatch, crgx)){
  std::cout << stime << std::endl;                   // Now it is 23:25.
  std::cout << "Time: " << smatch[0] << std::endl;   // Time: 23:25
}

// regular expression holder for time
std::wregex wrgx(L"([01]?[0-9]|2[0-3]):[0-5][0-9]");

// const wchar_t*
std::wcmatch wcmatch;

const wchar_t* wctime{L"Now it is 23:47."};
if (std::regex_search(wctime, wcmatch, wrgx)){
  std::wcout << wctime << std::endl;                 // Now it is 23:47.
  std::wcout << "Time: " << wcmatch[0] << std::endl; // Time: 23:47
}

// std::wstring
std::wsmatch wsmatch;

std::wstring  wstime{L"Now it is 00:03."};
if (std::regex_search(wstime, wsmatch, wrgx)){
  std::wcout << wstime << std::endl;                  // Now it is 00:03.
  std::wcout << "Time: " << wsmatch[0] << std::endl;  // Time: 00:03
}

    QByteArray bytes="hello world 112";
    std::regex reg("((\\s+)|([a-z]+)|(\\d+))+");
    std::match_results<QByteArray::iterator> matches;
    std::regex_search(bytes.begin(),bytes.end(),matches,reg);
    for(auto& v : matches){
        qDebug()<<v.first;
    }

match

#include <regex>
...

std::string numberRegEx(R"([-+]?([0-9]*\.[0-9]+|[0-9]+))");
std::regex rgx(numberRegEx);
const char* numChar{"2011"};

if (std::regex_match(numChar, rgx)){
  std::cout << numChar << " is a number." << std::endl;
}                                            // 2011 is a number.

const std::string numStr{"3.14159265359"};
if (std::regex_match(numStr, rgx)){
  std::cout << numStr << " is a number." << std::endl;
}                                           // 3.14159265359 is a number.

const std::vector<char> numVec{{'-', '2', '.', '7', '1', '8', '2',
                                '8', '1', '8', '2', '8'}};
if (std::regex_match(numVec.begin(), numVec.end(), rgx)){
    for (auto c: numVec){ std::cout << c ;};
    std::cout << " is a number." << std::endl;
}                                           // -2.718281828 is a number.

replace

string future{"Future"};
string unofficialName{"The unofficial name of the new C++ standard is C++0x."};

regex rgxCpp{R"(C\+\+0x)"};
string newCppName{"C++11"};
string newName{regex_replace(unofficialName, rgxCpp, newCppName)};

regex rgxOff{"unofficial"};
string makeOfficial{"official"};
string officialName{regex_replace(newName, rgxOff, makeOfficial)};

cout << officialName << endl;
                          // The official name of the new C++ standard is C++11.

filter

std::string future{"Future"};
const std::string unofficial{"unofficial, C++0x"};
const std::string official{"official, C++11"};

std::regex regValues{"(.*),(.*)"};
std::string standardText{"The $1 name of the new C++ standard is $2."};
std::string textNow= std::regex_replace(unofficial, regValues, standardText);
std::cout << textNow << std::endl;
                        // The unofficial name of the new C++ standard is C++0x.

std::smatch smatch;
if (std::regex_match(official, smatch, regValues)){
  std::cout << smatch.str();                                   // official,C++11
  std::string textFuture= smatch.format(standardText);
  std::cout << textFuture << std::endl;
}                       // The official name of the new C++ standard is C++11.