Skip to content
C++

std::string and String Manipulation

In C++, std::string is the standard library class for storing and manipulating text. Unlike C-style character arrays (which require manual memory management and null-termination), std::string handles its own memory automatically, grows on demand, and provides a rich set of member functions for searching, slicing, comparing, and modifying text. You should use std::string whenever you need to work with text in modern C++ — raw character arrays are a C API concern, not an everyday tool.

Creating strings

A std::string can be constructed from a string literal, from another string, from repeated characters, or left empty. The #include <string> header is required (though it is often pulled in transitively by other headers).

#include <string>

std::string empty;                    // empty string ""
std::string name = "Alice";           // from string literal
std::string greeting("Hello");        // direct construction
std::string copy = name;              // copy of name
std::string repeated(5, 'x');         // "xxxxx" — 5 copies of 'x'

std::cout << name.size();    // 5  — number of characters
std::cout << name.length();  // 5  — same as size()
std::cout << name.empty();   // 0 (false) — true only if size() == 0

Concatenation and modification

The + operator concatenates two strings into a new string. The += operator appends to the end in place. Individual characters are accessed and modified with the [] operator or the bounds-checked at() method.

std::string first = "Hello";
std::string space = " ";
std::string last  = "World";

std::string full = first + space + last;  // "Hello World"
full += "!";                              // "Hello World!"

// Individual characters (0-indexed):
char c = full[0];        // 'H'
full[0] = 'h';           // "hello World!"

// at() throws std::out_of_range if index is invalid:
char safe = full.at(0);   // 'h'

// Iterating characters:
for (char ch : full) {
    std::cout << ch;
}

// Using indices:
for (std::size_t i = 0; i < full.size(); ++i) {
    full[i] = std::toupper(full[i]);
}

Comparison

std::string supports all comparison operators (==, !=, <, >, etc.) with lexicographic (dictionary) ordering. Unlike C-style strings, you do not need strcmp — just use ==.

std::string a = "apple";
std::string b = "banana";

if (a == b)  std::cout << "equal";
if (a != b)  std::cout << "not equal";    // prints this
if (a < b)   std::cout << "a comes first"; // true: 'a' < 'b'

// Compare with a literal directly:
if (a == "apple") std::cout << "yes";     // fine — literal is converted

Searching and substrings

find() returns the index of the first occurrence of a substring, or std::string::npos (a special large value) if not found. substr(pos, len) extracts a portion of the string.

std::string sentence = "the quick brown fox";

// find — returns index or npos:
std::size_t pos = sentence.find("quick");
if (pos != std::string::npos) {
    std::cout << "Found at index " << pos;  // Found at index 4
}

// substr(start_position, length):
std::string word = sentence.substr(4, 5);  // "quick"
std::string rest = sentence.substr(4);      // "quick brown fox" (to end)

// Replace a portion:
sentence.replace(4, 5, "slow");  // "the slow brown fox"

// Check prefix/suffix (C++20):
// sentence.starts_with("the")  → true
// sentence.ends_with("fox")    → true

Converting between strings and numbers

The standard library provides free functions for converting numbers to strings and strings to numbers. std::to_string() converts any arithmetic type to a string. The stoi, stod, and similar functions parse a string and return the numeric value.

#include <string>

// Number to string:
int n = 42;
std::string s = std::to_string(n);   // "42"
double d = 3.14;
std::string t = std::to_string(d);   // "3.140000"

// String to number (throws std::invalid_argument or std::out_of_range on error):
int parsed  = std::stoi("123");      // 123
double fp   = std::stod("3.14");     // 3.14
long long big = std::stoll("9999999999"); // long long version

For formatted output (e.g., 2 decimal places), prefer std::format (C++20) or std::ostringstream over std::to_string.

Quick reference

OperationCode
Lengths.size() or s.length()
Empty checks.empty()
Access characters[i] or s.at(i) (bounds-checked)
Append strings += other or s.append(other)
Append characters += 'x' or s.push_back('x')
Concatenates + t (produces new string)
Find substrings.find(sub) → index or npos
Extract substrings.substr(pos, len)
Replace portions.replace(pos, len, replacement)
Clear contentss.clear()
Remove characterss.erase(pos, len)
Insert texts.insert(pos, text)
First characters.front()
Last characters.back()
C-string pointers.c_str() (for C APIs)

Key rules to remember

Use std::string instead of char arrays for all text in modern C++

std::string manages memory automatically, prevents buffer overflows, and provides a rich API. char arrays are a C legacy.

Pass std::string by const reference to avoid expensive copies

void f(const std::string& s) avoids copying the string's internal buffer. Pass by value only if the function needs its own copy.

Check find() result against std::string::npos before using it

If the substring is not found, find() returns npos (a very large number). Using it as an index causes undefined behavior.

std::string operator[] does not bounds-check — use at() when the index might be out of range

s[i] is undefined behavior if i >= s.size(). s.at(i) throws std::out_of_range instead.

Sign in to track progress