The first operator[]() method allows you to access an individual element of a string by using array notation; it can be used to retrieve or alter the value. The second operator[]() method can be used with const objects, and it can be used only to retrieve the value:
string word("tack");
cout << word[0]; // display the t
word[3] = 't'; // overwrite the k with a t
const ward("garlic");
cout << ward[2]; // display the r
The at() methods provide similar access, except that the index is provided in function argument notation:
string word("tack");
cout << word.at(0); // display the t
The difference (besides the syntax difference) is that the at() methods provide bounds checking and throw an out_of_range exception if pos >= size(). Note that pos is type size_type, which is unsigned; therefore, a negative value is impossible for pos. The operator[]() methods don’t do bounds checking, so the behavior is undefined if pos >= size(), except that the const version returns the null character equivalent if pos == size().
Thus, you get a choice between safety (using at() and testing for exceptions) and execution speed (using array notation).
There is also a function that returns a new string that is a substring of the original:
basic_string substr(size_type pos = 0, size_type n = npos) const;
It returns a string that’s a copy of the string starting at position pos and going for n characters or to the end of the string, whichever comes first. For example, the following initializes pet to "donkey":
string message("Maybe the donkey will learn to sing.");
string pet(message.substr(10, 6));
C++11 adds these four access methods:
const charT& front() const;
charT& front();
const charT& back() const;
charT& back();
The front() methods access the first element of a string, acting like operator[](0). The back() methods access the last element of a string, acting like operator[](size() - 1).
Basic Assignment
C++11 has five overloaded assignment methods, up two from C++98:
basic_string& operator=(const basic_string& str);
basic_string& operator=(const charT* s);
basic_string& operator=(charT c);
basic_string& operator=(basic_string&& str) noexcept; // C++11
basic_string& operator=(initializer_list
The first assigns one string object to another, the second assigns a C-style string to a string object, the third assigns a single character to a string object, the fourth uses move semantics to assign an rvalue string object to a string object, and the fifth allows assignment of an initializer list. Thus, all the following operations are possible:
string name("George Wash");
string pres, veep, source, join, awkward;
pres = name;
veep = "Road Runner";
source = 'X';
join = name + source; // now with move semantics!
awkward = {'C','l','o','u','s','e','a','u'};
String Searching
The string class provides six search functions, each with four prototypes. The following sections describe them briefly.
The find() Family
Here are the find() prototypes as provided by C++11:
size_type find (const basic_string& str, size_type pos = 0) const noexcept;
size_type find (const charT* s, size_type pos = 0) const;
size_type find (const charT* s, size_type pos, size_type n) const;
size_type find (charT c, size_type pos = 0) const noexcept;
The first member returns the beginning position of the str substring’s first occurrence in the invoking object, with the search beginning at position pos. If the substring is not found, the method returns npos.
Here’s code for finding the location of the substring "hat" in a longer string:
string longer("That is a funny hat.");
string shorter("hat");
size_type loc1 = longer.find(shorter); // sets loc1 to 1
size_type loc2 = longer.find(shorter, loc1 + 1); // sets loc2 to 16
Because the second search begins at position 2 (the a in That), the first occurrence of hat it finds is near the end of the string. To test for failure, you use the string::npos value:
if (loc1 == string::npos)
cout << "Not found\n";
The second method does the same thing, except that it uses an array of characters instead of a string object as the substring:
size_type loc3 = longer.find("is"); //sets loc3 to 5
The third method does the same as the second, except that it uses only the first n characters of the string s. The effect is the same as using the basic_string(const charT* s, size_type n) constructor and using the resulting object as the string argument to the first form of find(). For example, the following searches for the substring "fun":
size_type loc4 = longer.find("funds", 3); //sets loc4 to 10
The fourth method does the same thing as the first, except that it uses a single character instead of a string object as the substring:
size_type loc5 = longer.find('a'); //sets loc5 to 2
The rfind() Family
The rfind() methods have these prototypes:
size_type rfind(const basic_string& str,
size_type pos = npos) const noexcept;