The string class

Introduction

In C, text means managing arrays of characters by hand, with all the bugs that brings. C++ gives you std::string, which grows as needed and works with the operators you would expect. It is one of the biggest everyday improvements C++ makes.

How it works

CodeResult
s.size()the number of characters
s[i]the character at index i
s + t, s += tjoined text
s == t, s < tcomparison
s.substr(pos, len)a piece of the string
s.find("x")the first position, or string::npos
s.empty()whether it has no characters
s.insert(pos, t), s.erase(pos, n)changes the string
stoi(s), to_string(n)convert to and from a number

Characters. A range-based loop goes through the characters. for (char& c : s) lets you change them. toupper(c) and tolower(c) come from <cctype>.

Not found. find returns the special value string::npos if there is no match, so always compare with that before using the result.

String streams. <sstream> lets you treat a string as if it were input. It is the simplest way of splitting a line into words:

#include <iostream>
#include <sstream>
#include <string>
using namespace std;

int main() {
    string line = "the quick brown fox";
    istringstream in(line);
    string word;
    int count = 0;
    while (in >> word) {
        count++;
    }
    cout << count << " words" << endl;
    ostringstream out;
    out << count * 2 << "!";
    cout << out.str() << endl;
    return 0;
}
Open in compiler

ostringstream works the other way round, building text with <<.

Syntax

string s = "hello";
s += " world";
if (s.find("wor") != string::npos) { ... }
int n = stoi("42");
string t = to_string(n);

Example

#include <iostream>
#include <string>
using namespace std;

int main() {
    string city = "Dhaka";
    cout << city.size() << " " << city[0] << endl;
    city += " City";
    cout << city.substr(0, 5) << endl;
    cout << city.find("City") << endl;
    string other = "Dhaka City";
    cout << (city == other) << endl;
    return 0;
}
Open in compiler

Line by line

  1. city.size() is 5, and city[0] is the first character.
  2. += adds to the end, and the string grows by itself.
  3. substr(0, 5) takes five characters from the start.
  4. find gives the position where "City" begins.
  5. == compares the text, and prints 1 for true.

Expected result

5 D
Dhaka
6
1

In the real world

Almost every program handles text, whether it is configuration, messages or file names. Using std::string rather than character arrays removes a whole class of security bugs.

Common mistakes

  • Not checking for string::npos before using the result of find.
  • Using s[i] past the end. It is not checked, so use s.at(i) if you are unsure.
  • Using stoi on text that is not a number. It throws an exception.
  • Adding two quoted texts. "a" + "b" is an error, because neither is a string yet.

Best practices

  • Pass strings to functions by const string&.
  • Use istringstream to split lines.
  • Prefer string to character arrays in all new code.

Summary

std::string handles its own memory and supports +, ==, substr, find and more. find signals failure with string::npos, and string streams split and build text.

Quick check

1. What is string("hello").substr(1, 3)?
2. What does s.find("z") return when there is no z?
3. How do you compare the text of two strings?
4. Which header lets you split a line with istringstream?

Key takeaways

  • A string manages its own memory.
  • Compare strings with ==.
  • find returns string::npos when there is no match.

Practice problems for this lesson

My notes

Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.