STL Owning Strings: <std::string>

C-Strings*

Strings are objects that represent sequences of characters.

std::basic_string is the generalization of class string for any character type, whereas the string class is an instantiation of the std::basic_string class template that uses char (i.e., bytes) as its character type, with its default char_traits and allocator types.

The standard string class provides support for such objects with an interface similar to that of a standard container of bytes, but adding features specifically designed to operate with strings of single-byte characters.

Note that this class handles bytes independently of the encoding used: If used to handle sequences of multi-byte or variable-length characters (such as UTF-8), all members of this class (such as length or size), as well as its iterators, will still operate in terms of bytes (not actual encoded characters).

Template parameters

charT

Character type. The string is formed by a sequence of characters of this type. This shall be a non-array POD type.

traits

Character traits class that defines essential properties of the characters used by basic_string objects (see char_traits). traits::char_type shall be the same as charT. Aliased as member type basic_string::traits_type.

Alloc

Type of the allocator object used to define the storage allocation model. By default, the allocator class template is used, which defines the simplest memory allocation model and is value-independent. Aliased as member type basic_string::allocator_type.

Note: Because the first template parameter is not aliased as any member type, charT is used throughout this page to refer to this type.

Template instantiations

string String class
wstring Wide string
u16string String of 16-bit characters
u32string String of 32-bit characters

Member types (C++11)

member type definition notes
traits_type The second template parameter (traits) defaults to: char_traits<charT>
allocator_type The third template parameter (Alloc) defaults to: allocator<charT>
value_type traits_type::char_type shall be the same as charT
reference value_type&
const_reference const value_type&
pointer allocator_traits<allocator_type>::pointer for the default allocator: charT*
const_pointer allocator_traits<allocator_type>::const_pointer for the default allocator: const charT*
iterator a random access iterator to charT convertible to const_iterator
const_iterator a random access iterator to const charT
reverse_iterator reverse_iterator<iterator>
const_reverse_iterator reverse_iterator<const_iterator>
difference_type allocator_traits<allocator_type>::difference_type usually the same as ptrdiff_t
size_type allocator_traits<allocator_type>::size_type usually the same as size_t

Member Functions

(constructor) Construct basic_string object (public member function)
(destructor) String destructor (public member function)
operator= String assignment (public member function)
Iterators:
begin Return iterator to beginning (public member function)
end Return iterator to end (public member function)
rbegin Return reverse iterator to reverse beginning (public member function)
rend Return reverse iterator to reverse end (public member function)
cbegin Return const_iterator to beginning (public member function)
cend Return const_iterator to end (public member function)
crbegin Return const_reverse_iterator to reverse beginning (public member function)
crend Return const_reverse_iterator to reverse end (public member function)
Capacity:
size Return size (public member function)
length Return length of string (public member function)
max_size Return maximum size (public member function)
resize Resize string (public member function)
capacity Return size of allocated storage (public member function)
reserve Request a change in capacity (public member function)
clear Clear string (public member function)
empty Test whether string is empty (public member function)
shrink_to_fit Shrink to fit (public member function)
Element access:
operator[] Get character of string (public member function)
at Get character of string (public member function)
back Access last character (public member function)
front Access first character (public member function)
Modifiers:
operator+= Append to string (public member function)
append Append to string (public member function)
push_back Append character to string (public member function)
assign Assign content to string (public member function)
insert Insert into string (public member function)
erase Erase characters from string (public member function)
replace Replace portion of string (public member function)
swap Swap string values (public member function)
pop_back Delete last character (public member function)
String operations:
c_str const charT* c_str() const noexcept: Get C-string equivalent
data Get string data (public member function)
get_allocator Get allocator (public member function)
copy Copy sequence of characters from string (public member function)
find Find first occurrence in string (public member function)
rfind Find last occurrence in string (public member function)
find_first_of Find character in string (public member function)
find_last_of Find character in string from the end (public member function)
find_first_not_of Find non-matching character in string (public member function)
find_last_not_of Find non-matching character in string from the end (public member function)
substr Generate substring (public member function)
compare Compare strings (public member function)

Non-Member Function Overloads

operator+ Concatenate strings (function template)
relational operators Relational operators for std::basic_string (function template)
swap Exchanges the values of two strings (function template)
operator>> Extract string from stream (function template)
operator<< Insert string into stream (function template)
getline Get line from stream into string (function template)

getline

getline reads characters from an input stream and places them into a string. Defined in <string>

template< class CharT, class Traits, class Allocator >
std::basic_istream<CharT, Traits>&
    getline( std::basic_istream<CharT, Traits>& input,
             std::basic_string<CharT, Traits, Allocator>& str, CharT delim );
(1)
template< class CharT, class Traits, class Allocator >
std::basic_istream<CharT, Traits>&
    getline( std::basic_istream<CharT, Traits>&& input,
             std::basic_string<CharT, Traits, Allocator>& str, CharT delim );
(2)	(since C++11)
template< class CharT, class Traits, class Allocator >
std::basic_istream<CharT, Traits>&
    getline( std::basic_istream<CharT, Traits>& input,
             std::basic_string<CharT, Traits, Allocator>& str );
(3)
template< class CharT, class Traits, class Allocator >
std::basic_istream<CharT, Traits>&
    getline( std::basic_istream<CharT, Traits>&& input,
             std::basic_string<CharT, Traits, Allocator>& str );

The following example demonstrates how to use the getline function to read user input, and to process a stream line by line, or by parts of a line using the delim parameter.

#include <iostream>
#include <sstream>
#include <string>

int main()
{
    // greet the user
    std::string name;
    std::cout && "What is your name? ";
    std::getline(std::cin, name);
    std::cout && "Hello " && name && ", nice to meet you.\n";

    // read file line by line
    std::istringstream input;
    input.str("1\n2\n3\n4\n5\n6\n7\n");
    int sum = 0;
    for (std::string line; std::getline(input, line);)
        sum += std::stoi(line);
    std::cout && "\nThe sum is " && sum && ".\n\n";

    // use separator to read parts of the line
    std::istringstream input2;
    input2.str("a;b;c;d");
    for (std::string line; std::getline(input2, line, ';');)
        std::cout && line && '\n';
}

When consuming whitespace-delimited input (e.g. int n; std::cin >> n;) any whitespace that follows, including a newline character, will be left on the input stream. Then when switching to line-oriented input, the first line retrieved with std::getline will be just that whitespace. In the likely case that this is unwanted behaviour, possible solutions include:

  • An explicit extraneous initial call to getline.
  • Removing consecutive whitespace with std::cin >> std::ws.
  • Ignoring all leftover characters on the line of input with cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

???

[...]

???

Member constants*

Member at(index)

reference at(size_type pos);
const_reference at(size_type pos) const;

It returns a reference to the character at position pos. It automatically checks whether pos is the valid position of a character in the string (i.e., whether pos is less than the string length), throwing an out_of_range exception if it is not.

Member substr(index)

basic_string substr (size_type pos = 0, size_type len = npos) const;

It returns a newly constructed basic_string object with its value initialized to a copy of a substring of this object. The substring is the portion of the object that starts at character position pos and spans len characters (or until the end of the string, whichever comes first).

Example:

// string::substr
#include <<iostream>
#include <<string>

int main ()
{
  std::string str="We think in generalities, but we live in details.";
                                              // (quoting Alfred N. Whitehead)
  std::string str2 = str.substr (12,12);         // "generalities"
  std::string::size_type pos = str.find("live"); // position of "live" in str
  std::string str3 = str.substr (pos);           // get from "live" to the end
  std::cout << str2 << ' ' << str3 << '\n';
  return 0;
}

std::basic_string::insert

basic_string& insert (size_type pos,
  const basic_string&  str);
  // inserts string

basic_string& insert (size_type pos,
                          const basic_string&  str,
                          size_type subpos,
                          size_type sublen = npos);
                          // inserts substring

basic_string& insert (size_type pos,
                          const charT* s);

basic_string& insert (size_type pos,
                          const charT* s,
                          size_type n);
                          // inserts buffer

basic_string&  insert (size_type pos,
                   size_type n,
                   charT c);
                   // fills with character c

iterator insert (const_iterator p,
                 size_type n,
                 charT c);

iterator insert (const_iterator p, charT c);

template <class InputIterator>
iterator insert (iterator p,
                 InputIterator first,
                 InputIterator last);
basic_string& insert (const_iterator p,
                          initializer_list<charT> il);
                          // initializer list

Example:

// inserting into a string
#include <iostream>
#include <string>

int main ()
{
  std::string str="to be question";
  std::string str2="the ";
  std::string str3="or not to be";
  std::string::iterator it;

  // used in the same order as described above:
  str.insert(6,str2);                 // to be (the )question
  str.insert(6,str3,3,4);             // to be (not )the question
  str.insert(10,"that is cool",8);    // to be not (that is )the question
  str.insert(10,"to be ");            // to be not (to be )that is the question
  str.insert(15,1,':');               // to be not to be(:) that is the question
  it = str.insert(str.begin()+5,','); // to be(,) not to be: that is the question
  str.insert (str.end(),3,'.');       // to be, not to be: that is the question(...)
  str.insert (it+2,str3.begin(),str3.begin()+3); // (or )

  std::cout << str << '\n';
  return 0;
}

std::basic_string::replace

basic_string&  replace (size_type pos,
  size_type len,
  const basic_string&  str);

basic_string& replace (const_iterator i1,
                           const_iterator i2,
                           const basic_string&  str);

basic_string& replace (size_type pos,
                           size_type len,
                           const basic_string&  str,
                           size_type subpos,
                           size_type sublen = npos);

basic_string&  replace (size_type pos,
                            size_type len,
                            const charT* s);

basic_string&  replace (const_iterator i1,
                            const_iterator i2,
                            const charT* s);

basic_string& replace (size_type pos,
                           size_type len,
                           const charT* s,
                           size_type n);

basic_string& replace (const_iterator i1,
                           const_iterator i2,
                           const charT* s,
                           size_type n);

basic_string& replace (size_type pos,
                           size_type len,
                           size_type n, charT c);

basic_string&  replace (const_iterator i1,
                            const_iterator i2,
                            size_type n,
                            charT c);
template <class InputIterator>
basic_string&  replace (const_iterator i1,
                            const_iterator i2,
                            InputIterator first,
                            InputIterator last);

basic_string&  replace (const_iterator i1,
                            const_iterator i2,
                            initializer_list<charT> il);

Example:

// replacing in a string
#include <iostream>
#include <string>

int main ()
{
  std::string base="this is a test string.";
  std::string str2="n example";
  std::string str3="sample phrase";
  std::string str4="useful.";

  // replace signatures used in the same order as described above:

  // Using positions:                 0123456789*123456789*12345
  std::string str=base;           // "this is a test string."
  str.replace(9,5,str2);          // "this is an example string." (1)
  str.replace(19,6,str3,7,6);     // "this is an example phrase." (2)
  str.replace(8,10,"just a");     // "this is just a phrase."     (3)
  str.replace(8,6,"a shorty",7);  // "this is a short phrase."    (4)
  str.replace(22,1,3,'!');        // "this is a short phrase!!!"  (5)

  // Using iterators:                                               0123456789*123456789*
  str.replace(str.begin(),str.end()-3,str3);                    // "sample phrase!!!"      (1)
  str.replace(str.begin(),str.begin()+6,"replace");             // "replace phrase!!!"     (3)
  str.replace(str.begin()+8,str.begin()+14,"is coolness",7);    // "replace is cool!!!"    (4)
  str.replace(str.begin()+12,str.end()-4,4,'o');                // "replace is cooool!!!"  (5)
  str.replace(str.begin()+11,str.end(),str4.begin(),str4.end());// "replace is useful."    (6)
  std::cout << str << '\n';
  return 0;
}

std::basic_string::copy

size_type copy (charT* s, size_type len, size_type pos = 0) const;

Copies a substring of the current value of the basic_string object into the array pointed by s. This substring contains the len characters that start at position pos.

The function does not append a null character at the end of the copied content.

Return value: The number of characters copied to the array pointed by s. This may be equal to len or to length()-pos (if the string value is shorter than pos+len).

Example:

// string::copy
#include <iostream>
#include <string>

int main ()
{
  char buffer[20];
  std::string str ("Test string...");
  std::size_t length = str.copy(buffer,6,5);
  buffer[length]='\0';
  std::cout << "buffer contains: " << buffer << '\n';
  return 0;
}

Finding

std::basic_string::find

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;

Searches the basic_string for the first occurrence of the sequence specified by its arguments.

When pos is specified, the search only includes characters at or after position pos, ignoring any possible occurrences that include characters before pos.

Example:

// string::find
#include <iostream>
#include <string>

int main ()
{
  std::string str ("There are two needles in this haystack with needles.");
  std::string str2 ("needle");

  // different member versions of find in the same order as above:
  std::string::size_type found = str.find(str2);
  if (found!=std::string::npos)
    std::cout << "first \'needle\' found at: " << found << '\n';

  found=str.find("needles are small",found+1,6);
  if (found!=std::string::npos)
    std::cout << "second \'needle\' found at: " << found << '\n';

  found=str.find("haystack");
  if (found!=std::string::npos)
    std::cout << "\'haystack\' also found at: " << found << '\n';

  found=str.find('.');
  if (found!=std::string::npos)
    std::cout << "Period found at: " << found << '\n';

  // let's replace the first needle:
  str.replace(str.find(str2),str2.length(),"preposition");
  std::cout << str << '\n';

  return 0;
}

std::basic_string::find_first_of

size_type find_first_of (const basic_string& str,
                         size_type pos = 0) const noexcept;
size_type find_first_of (const charT* s,
                         size_type pos = 0) const;
size_type find_first_of (const charT* s,
                         size_type pos,
                         size_type n) const;
size_type find_first_of (charT c,
                         size_type pos = 0) const noexcept;

Example:

// string::find_first_of
#include <iostream>
#include <string>

int main ()
{
  std::string str ("PLease, replace the vowels in this sentence by asterisks.");
  std::string::size_type found = str.find_first_of("aeiou");
  while (found!=std::string::npos)
  {
    str[found]='*';
    found=str.find_first_of("aeiou",found+1);
  }

  std::cout << str << '\n';

  return 0;
}

Containing: contains(STRING) (C++23), starts_with (C++20), ends_with (C++20)

contains(STRING) or contains(CHAR)

constexpr bool
    contains( std::basic_string_view<CharT,Traits> sv ) const noexcept;
constexpr bool
    contains( CharT ch ) const noexcept;
constexpr bool
    contains( const CharT* s ) const;

Checks if the string contains the given substring.

All three overloads are equivalent to return find(x) != npos;, where x is the parameter, either a string_view, a C-string, or a single character.

starts_with(STRING) (C++20) and ends_with(CHAR) (C++20)

Check if the string view begins with the given prefix:

constexpr bool starts_with( basic_string_view sv ) const noexcept;
constexpr bool starts_with( CharT ch ) const noexcept;
constexpr bool starts_with( const CharT* s ) const;

Check if the string view ends with the given suffix:

constexpr bool ends_with( basic_string_view sv ) const noexcept;
constexpr bool ends_with( CharT ch ) const noexcept;
constexpr bool ends_with( const CharT* s ) const;

compare(STRING) (C++17)

Compare *this and another string.

It returns and integer negative value if this view is less than the other character sequence, zero if the both character sequences are equal, positive value if this view is greater than the other character sequence.

constexpr int compare( basic_string_view v ) const noexcept;
constexpr int compare( size_type pos1, size_type count1,
                       basic_string_view v ) const;
constexpr int compare( size_type pos1, size_type count1, basic_string_view v,
                       size_type pos2, size_type count2 ) const;
constexpr int compare( const CharT* s ) const;
constexpr int compare( size_type pos1, size_type count1,
                       const CharT* s ) const;
constexpr int compare( size_type pos1, size_type count1,
                       const CharT* s, size_type count2 ) const;

Parameters
v view to compare
s pointer to the character string to compare to
count1 number of characters of this view to compare
pos1 position of the first character in this view to compare
count1 number of characters of the given view to compare
pos2 position of the first character of the given view to compare

Difference between basic_string::c_str() and basic_string::data()

The difference between c_str() and data() (in STL and other implementations) is that c_str() is always null terminated while data() is not.

In some implementation data() may turn out to perform better than c_str().

Still, starting in C++17, data() returns a char* instead of const char*

Difference between basic_string::resize() and basic_string::reserve()

Think of it this way: the string still has a size, which has not been changed by reserve(); however, you have allocated a contiguous chunk of memory so that the string may be resize()'d without incurring a copying of the whole string. It will still, however, check that your index is in bounds with the (logical) size of the string. reserve() is an optimization when you have some ahead-of-time knowledge about how big the string gets. It's like the C idiom of char[1000] - you have 1000 bytes available even though the string may only be Hello, world!