C++ Cheatsheet

Strings

Use this C++ reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

std::string Basics

#include <string>

std::string s;                        // empty string
std::string s1 = "hello";            // from string literal
std::string s2("hello");             // same
std::string s3(5, 'x');              // "xxxxx"
std::string s4(s1, 1, 3);           // s1 starting at index 1, length 3: "ell"
std::string s5(s1.begin(), s1.begin() + 3); // from iterators: "hel"

// Size / empty
s.size();          // number of chars (same as length())
s.length();
s.empty();         // true if size() == 0
s.max_size();      // theoretical max
s.capacity();      // allocated capacity
s.reserve(100);    // allocate space for at least 100 chars
s.shrink_to_fit(); // release excess capacity

Access and Iteration

std::string s = "hello";

s[0];           // 'h' — no bounds check
s.at(0);        // 'h' — throws std::out_of_range if OOB
s.front();      // 'h'
s.back();       // 'o'
s.data();       // const char* (null-terminated since C++11)
s.c_str();      // const char* (always null-terminated)

// Iteration
for (char c : s) { /* ... */ }
for (char& c : s) { c = std::toupper(c); }
for (auto it = s.begin(); it != s.end(); ++it) { *it; }
s.rbegin(); s.rend();   // reverse iterators

Modifiers

std::string s = "hello";

// Append
s += " world";            // operator+=
s.append(" world");
s.append(3, '!');         // append 3 '!'
s.append(other, 2, 4);   // append other starting at 2, length 4
s.push_back('!');         // append single char

// Insert
s.insert(5, " world");    // insert at position 5
s.insert(s.begin() + 5, ' ');
s.insert(5, 3, '!');      // insert 3 '!' at position 5

// Erase
s.erase(5);               // erase from position 5 to end
s.erase(5, 3);            // erase 3 chars starting at position 5
s.erase(it);              // erase at iterator
s.erase(first, last);     // erase range
s.pop_back();             // remove last char

// Replace
s.replace(0, 5, "HELLO"); // replace positions 0–4 with "HELLO"
s.replace(first, last, "NEW");

// Assign
s.assign("new value");
s.assign(5, 'z');          // "zzzzz"
s.clear();                  // empty string

// Resize
s.resize(10);              // truncate or extend with '\0'
s.resize(10, '*');         // extend with '*'

Search and Find

All return std::string::npos (maximum size_t) on failure.

std::string s = "hello world hello";

s.find("hello");           // 0 — first occurrence
s.find("hello", 1);        // 12 — start searching from position 1
s.find('o');               // 4
s.rfind("hello");          // 12 — last occurrence
s.rfind("hello", 11);      // 0  — search backward from position 11

s.find_first_of("aeiou");  // 1 ('e') — first char in set
s.find_last_of("aeiou");   // 16 ('o') — last char in set
s.find_first_not_of("helo"); // 5 (' ')
s.find_last_not_of("dlro "); // 13 ('e') — last char not in set

// Check presence
if (s.find("world") != std::string::npos) { /* found */ }
s.contains("world");       // bool (C++23)
s.starts_with("hello");    // bool (C++20)
s.ends_with("hello");      // bool (C++20)

Substrings and Comparison

std::string s = "hello world";

s.substr(6);        // "world"
s.substr(6, 3);     // "wor" (start, length)

s.compare("hello world");  // 0 if equal, <0 if less, >0 if greater
s.compare(6, 5, "world");  // compare s[6..10] with "world"

// Operators: == != < > <= >= (lexicographic)
s == "hello world";   // true
s < "hello worldz";   // true

Conversion: String ↔ Number

#include <string>

// Number → string
std::string s1 = std::to_string(42);         // "42"
std::string s2 = std::to_string(3.14);       // "3.140000"
std::string s3 = std::to_string(-7LL);       // "-7"

// String → number (throw std::invalid_argument or std::out_of_range)
int    i  = std::stoi("42");         // 42
long   l  = std::stol("42");
long long ll = std::stoll("42");
unsigned long ul = std::stoul("42");
float  f  = std::stof("3.14");       // 3.14f
double d  = std::stod("3.14");       // 3.14
long double ld = std::stold("3.14");

// With base
int hex = std::stoi("FF", nullptr, 16); // 255
int bin = std::stoi("1010", nullptr, 2); // 10

// With position out (fills with index of first unconverted char)
std::size_t pos;
int n = std::stoi("42abc", &pos);   // n=42, pos=2

// C++17: std::from_chars / to_chars (no allocation, no exceptions, fastest)
#include <charconv>
char buf[32];
auto [ptr, ec] = std::to_chars(buf, buf + sizeof(buf), 42);
// ec == std::errc{} on success

int val;
auto [p2, ec2] = std::from_chars("42", "42" + 2, val);
// val == 42, ec2 == std::errc{}

Case, Trimming, and Character Classification (<cctype>)

#include <cctype>
#include <algorithm>

// Character classification (non-locale-aware — safer for ASCII)
std::isalpha('a');   // true (letter)
std::isdigit('5');   // true (digit)
std::isalnum('a');   // true (letter or digit)
std::islower('a');   // true
std::isupper('A');   // true
std::isspace(' ');   // true (' ', '\t', '\n', '\r', '\f', '\v')
std::isprint('a');   // true (printable, including space)
std::isgraph('a');   // true (printable, excluding space)
std::ispunct(',');   // true

// Case conversion (on char; use unsigned char to avoid UB on negative chars)
std::toupper('a');   // 'A'
std::tolower('A');   // 'a'

// To uppercase / lowercase a whole string
std::string s = "Hello World";
std::transform(s.begin(), s.end(), s.begin(),
               [](unsigned char c){ return std::toupper(c); });
std::transform(s.begin(), s.end(), s.begin(),
               [](unsigned char c){ return std::tolower(c); });

// Trim (no built-in; typical implementations)
auto ltrim = [](std::string& s) {
    s.erase(s.begin(), std::find_if(s.begin(), s.end(),
        [](unsigned char c){ return !std::isspace(c); }));
};
auto rtrim = [](std::string& s) {
    s.erase(std::find_if(s.rbegin(), s.rend(),
        [](unsigned char c){ return !std::isspace(c); }).base(), s.end());
};

Split and Join

There is no built-in split. Common approaches:

#include <sstream>
#include <vector>
#include <string>

// Split by single delimiter character
std::vector<std::string> split(const std::string& s, char delim) {
    std::vector<std::string> tokens;
    std::istringstream iss(s);
    std::string token;
    while (std::getline(iss, token, delim)) tokens.push_back(token);
    return tokens;
}

// Split by whitespace (words)
std::vector<std::string> words;
std::istringstream iss("hello world foo");
std::string w;
while (iss >> w) words.push_back(w);

// C++20 ranges split view
#include <ranges>
for (auto part : std::views::split("a,b,c"sv, ',')) {
    std::string s(part.begin(), part.end());
}

// Join with separator
std::string join(const std::vector<std::string>& v, const std::string& sep) {
    std::string result;
    for (std::size_t i = 0; i < v.size(); ++i) {
        if (i) result += sep;
        result += v[i];
    }
    return result;
}

std::string_view (C++17)

A non-owning, read-only reference to a character sequence. Zero-copy replacement for const std::string& when ownership is not needed.

#include <string_view>

std::string_view sv = "hello";           // from string literal
std::string s = "world";
std::string_view sv2 = s;               // from std::string (no copy)

sv.size(); sv.empty(); sv.data();
sv[0]; sv.front(); sv.back();
sv.substr(1, 3);                        // returns string_view (no alloc)
sv.remove_prefix(2);                    // shrink front
sv.remove_suffix(2);                    // shrink back
sv.find("ll");
sv.starts_with("he"); sv.ends_with("lo");  // C++20
sv.contains("ell");                    // C++23

// Caution: sv must not outlive the string it references
std::string_view bad() {
    std::string s = "local";
    return s;       // UB: s is destroyed, sv dangling
}

Raw String Literals and Special Strings

// Raw string: no escape processing
std::string raw = R"(Hello\nWorld)";   // \n is literally backslash-n
std::string raw2 = R"(path\to\file)";

// Raw with custom delimiter (to include ")(" in the string)
std::string raw3 = R"delim(some "raw" (text) here)delim";

// String with embedded null (std::string handles it; c_str() stops at first null)
std::string sn("he\0llo", 6);   // length == 6

// Literal suffixes (C++14)
using namespace std::string_literals;
auto s = "hello"s;              // std::string
using namespace std::string_view_literals;
auto sv = "hello"sv;            // std::string_view

std::format for Strings (C++20)

#include <format>

std::string s = std::format("Name: {}, Age: {}", "Alice", 30);
std::string padded = std::format("{:>10}", "hi");      // "        hi"
std::string upper = std::format("{:^20}", "center");
std::cout << std::format("{:.5}", "truncated long string"); // "trunc"

C-Style Strings (<cstring>)

#include <cstring>

const char* cs = "hello";
char buf[64] = "hello";

std::strlen(cs);                  // length excluding null: 5
std::strcpy(buf, "world");        // copy (dst must be large enough)
std::strncpy(buf, "world", 63);   // safer — copies at most n chars
std::strcat(buf, "!");            // concatenate (dst must be large enough)
std::strncat(buf, "!", 1);
std::strcmp("abc", "abc");        // 0 if equal
std::strncmp("abc", "abd", 2);    // 0 (first 2 chars equal)
std::strchr(cs, 'l');             // pointer to first 'l', or null
std::strrchr(cs, 'l');            // pointer to last 'l'
std::strstr(cs, "ll");            // pointer to first "ll", or null

std::memcpy(dst, src, n);         // copy n bytes (may overlap: use memmove)
std::memmove(dst, src, n);        // copy n bytes (overlap-safe)
std::memset(buf, 0, sizeof(buf)); // fill with byte value
std::memcmp(a, b, n);             // compare n bytes

Prefer std::string and std::string_view over C strings in new code.