Skip to content
std::string
step 1/5

Reading — step 1 of 5

Learn

~3 min readStrings

std::string

If you arrive from C, this lesson is the payoff for all that null-terminator suffering: std::string is a real string type — it knows its length, grows on demand, cleans up after itself, and compares with == like a civilized value. If C++ is your first systems language: enjoy; you're skipping a generation of segfaults.

A value type that acts like one

#include <string>

std::string name = "Ada";
std::string full = name + " Lovelace";     // + concatenates
full += "!";                               // append in place

full.size()          // 13 — it KNOWS its length (O(1), no strlen walk)
full.empty()         // false
full == "Ada Lovelace!"   // true — == compares CONTENTS

Every line of that would be a function call, a buffer-size prayer, or a bug in C. Assignment copies, comparison compares text, destruction frees the memory — std::string behaves like int with letters in it, and that "value semantics" discipline is the heart of well-written C++.

Indexing and characters

std::string s = "hello";
s[0]            // 'h' — a char, mutable: s[0] = 'H' works!
s.front()       // 'h'
s.back()        // 'o'
s.at(99)        // throws an exception — bounds-CHECKED access
s[99]           // undefined behavior — unchecked, C-style speed

The [] vs .at() pair is a C++ signature you'll see again on vector: the fast door that trusts you and the checked door that throws. Note strings are mutable here (unlike Go/Rust/Python) — in-place algorithms like reversal are natural.

The toolbox

s.substr(1, 3)              // "ell" — from index 1, length 3
s.find("lo")                // 3 — index, or std::string::npos if absent
s.find("xyz") == std::string::npos    // the "not found" test — memorize npos
std::to_string(42)          // "42"
std::stoi("123")            // 123 — string to int (throws on garbage)

And iteration — the modern range-for reads best:

for (char c : s) {
    std::cout << c << ' ';
}

(Byte-level honesty for later: std::string is a sequence of chars with no Unicode opinions — size() counts bytes, and non-ASCII text has the same multi-byte realities as every language. For this course's ASCII graders, chars are characters.)

Reading strings

std::cin >> word reads one whitespace-delimited token — perfect for word-shaped input. Whole lines need std::getline(std::cin, line); the classic gotcha is mixing them (>> leaves the newline in the buffer, and the next getline reads it as an empty line — the fix, when you meet it, is std::cin.ignore()).

Your exercise: Reverse a Word

Read a word, print it reversed. Multiple honest routes, each teaching something:

// 1. backwards index loop — the fundamentals
for (int i = s.size() - 1; i >= 0; i--) std::cout << s[i];
std::cout << '\n';

// 2. build a new string
std::string r(s.rbegin(), s.rend());    // reverse iterators, one line

// 3. mutate in place — the <algorithm> preview
std::reverse(s.begin(), s.end());

Write #1 at minimum — the index arithmetic (size()-1 down to 0) is the muscle this exercise exists to build, and one subtlety hides in it: size() returns an unsigned type, so for (unsigned i = s.size()-1; i >= 0; …) loops forever (unsigned is always ≥ 0). Use int i, or route #2/#3 — and you've just met the signed/unsigned comparison warning that -Wall will nag about for the rest of your C++ life.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…