Step 1 of 5 · Reading · ~4 min
Learn
Strings
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 std::out_of_range — 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)
for (char c : s) { // range-for: each char in turn
std::cout << c << ' '; // prints h, space, e, space, ... — "h e l l o "
}
(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: the trap that eats half your input
There are two doors in, and they are not interchangeable:
std::string s;
std::cin >> s; // for input "hello world" -> s == "hello"
// stops dead at the first space; "world" is left behind
std::getline(std::cin, s); // for input "hello world" -> s == "hello world"
// takes the whole line, spaces and all
>> is right when the input genuinely is one token — a number, a flag, a single word. Given two words it hands you a fragment without complaining, so the program looks perfect on every short example you tried. When the spec says "a line", read a line. (Follow-on gotcha, for when you meet it: >> leaves the newline in the buffer, so a later getline returns an empty line; std::cin.ignore() clears it.)
Your exercise: Reverse a Word
Despite the name, the input is a whole line — it may contain spaces, and one of the graded tests does. The starter already reads it with std::getline and already prints at the end; the statement in the middle is yours.
// s = "hello" s[0]=='h' s[4]=='o' s.size()==5
// 01234 i is a POSITION (a number); s[i] is the CHARACTER there
std::reverse(s.begin(), s.end()); // in place: s becomes "olleh"
std::string r(s.rbegin(), s.rend()); // or: build a reversed copy, s untouched
for (int i = s.size() - 1; i >= 0; i--) std::cout << s[i]; // or: walk backwards
std::reverse comes from <algorithm> (already included) and it prints nothing — it rearranges s and hands you back silence. Reverse the line, then fall straight into return 0;, and your output is byte-identical to a starter you never touched: empty. That is why the mistake is so hard to see, and why the std::cout line is already written for you.
Two mistakes worth recognising on sight, because this exercise catches a lot of people with them:
std::reverse(s.begin(), s.end()) // <- no semicolon; the statement never ended
return 0;
// main.cpp:9:37: error: expected ‘;’ before ‘return’
for (int i = s.size() - 1; i >= 0; i--) std::cout << i; // prints 43210, not olleh
Read that message the way the compiler meant it: it names return, but the caret it draws sits at the end of the line above, just past the closing ). Nothing is wrong with return — it is simply the first token reached after a statement you never finished. That is easy to lose when a call is spread over several lines. In the loop, i is a number and s[i] is a letter, so printing the counter gives you positions counting down. And size() returns an unsigned type: for (unsigned i = s.size()-1; i >= 0; ...) never ends, because unsigned is always ≥ 0 and stepping below zero wraps to 18446744073709551615. Nothing warns you — the grader reports errors, not warnings — so use int i, or take a one-line route.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…