Lecture 3 — Strings
Source: sc++/ch03.md Duration: 75 minutes
Learning Objectives
By the end of this lecture, students should be able to:
- Create
std::stringobjects and use.size(),.length(), and.empty() - Concatenate strings with
+and+=, and explain why"a" + "b"does not compile - Compare strings with
==and<, and explain why ASCII ordering matters - Access characters with
[]versus.at()and choose between them - Iterate through a string with a range-based
forloop - Find and extract substrings with
.find()and.substr() - Read a whole line with
std::getlineand avoid thecin >> ... getlinetrap - Convert between strings and numbers with
std::stoi,std::stod,std::to_string
Materials
- Live coding terminal with
g++(-std=c++23 -Wall -Wextra -pedantic) - A text editor projected for the class
- Copies of
sc++/ch03.mdfor reference
0. Welcome and Review (5 min)
Review multiple choice (from lecture 2): On a system where
intis 4 bytes, what issizeof(scores)forint scores[10]?- A. 4
- B. 10
- C. 14
- D. 40
- E. Ben got this wrong
Answer: D —
sizeofon a whole array is element size times element count.Quick reminder: today we move from single characters (
char) to sequences of characters (std::string)
1. Why std::string? (5 min)
- Chapter 2 showed you could shove text into a
chararray, but raw char arrays are painful:- you must track the length yourself
- you cannot resize them
==compares pointers, not content- a missing
'\0'terminator can crash the program
std::stringmanages its own memory, knows its own length, and provides a rich set of operations- Always
#include <string>— do not rely on<iostream>pulling it in for you
2. Creating Strings (5 min)
#include <iostream>
#include <string>
int main()
{
std::string empty; // ""
std::string greeting = "Hola"; // literal
std::string copy = greeting; // copy
std::string repeat(5, '!'); // "!!!!!"
std::cout << greeting << "\n";
}- A default-constructed string is empty, not uninitialized — unlike a bare
int std::string(count, char)repeats the charactercounttimes
3. Length, Size, and Empty (5 min)
std::string title = "Ice Ice Baby";
std::cout << title.size() << "\n"; // 12
std::cout << title.length() << "\n"; // 12
std::string nada;
if (nada.empty()) {
std::cout << "nothing here\n";
}.size()and.length()return the same value — pick whichever reads better.empty()returnstruefor a zero-length string- Both return
size_t— an unsigned type, so be careful comparing against signed ints
4. Concatenation (8 min)
std::string first = "Baby";
std::string second = " One More Time";
std::string hit = first + second; // Baby One More Time
std::string lyrics = "Bailamos";
lyrics += ", te quiero"; // appends in place+produces a new string;+=modifies the left-hand string- You can mix a
std::stringwith a char or literal on either side
Trap: "hello" + " world" does not compile. Both operands are const char*, not std::string. At least one side of + must be a real std::string. Fix: std::string("hello") + " world" or assign to a std::string first.
5. Comparing Strings (5 min)
std::string a = "Hanson";
std::string b = "Vanilla Ice";
if (a < b) {
std::cout << a << " comes first\n";
}==,!=,<,>,<=,>=all work- Comparison is character by character using ASCII values
- Uppercase letters sort before lowercase letters because
'Z'(90) <'a'(97) - Quick board exercise: does
"Zebra" < "apple"evaluate to true or false?
6. Accessing Characters (7 min)
std::string song = "MMMBop";
std::cout << song[0] << "\n"; // M
std::cout << song.at(3) << "\n"; // B
std::string shout = "hey!";
shout[0] = 'H'; // now "Hey!"[]is fast but has no bounds check — out-of-bounds is undefined behavior.at()throwsstd::out_of_rangeif the index is invalid- Both are writable, so you can modify characters in place
Tip: Use .at() when you are not 100% sure the index is valid. The small overhead is worth the early error.
7. Iterating Through a String (5 min)
std::string word = "Iris";
for (char c : word) {
std::cout << c << ' ';
}
std::cout << "\n"; // I r i s- Range-based
foris the cleanest way to iterate - If you need the index, use a traditional loop with
size_t:
for (size_t i = 0; i < word.size(); ++i) {
std::cout << word[i] << ' ';
}- Prefer
size_toverintto avoid signed/unsigned warnings
8. Finding and Extracting (8 min)
std::string line = "Ice Ice Baby";
size_t pos = line.find("Baby");
if (pos != std::string::npos) {
std::cout << "found at position " << pos << "\n"; // 8
}
std::string part = line.substr(8, 4); // "Baby"
std::string rest = line.substr(4); // "Ice Baby".find(needle)returns the position of the first match, orstd::string::nposif not foundstd::string::nposis a special “not found” sentinel — always check for it.substr(pos, len)extractslencharacters starting atpos; omitlento extract to the end
Finding and Replacing
std::string msg = "press play";
size_t pos = msg.find("play");
if (pos != std::string::npos) {
msg.replace(pos, 4, "stop");
}
std::cout << msg << "\n"; // press stop 9. Reading Input — getline and the Mix Trap (8 min)
std::string full_name;
std::cout << "enter your full name: ";
std::getline(std::cin, full_name);std::getline(std::cin, s)reads up to the newline, including spaces- Contrast with
std::cin >> s, which stops at whitespace
Trap: If you mix std::cin >> and std::getline, the newline left by >> gets consumed by the next getline, giving an empty string. Fix it with std::cin.ignore():
int age;
std::string name;
std::cin >> age;
std::cin.ignore(); // discard the leftover newline
std::getline(std::cin, name);10. Strings to/from Numbers (7 min)
std::string year_str = "1997";
int year = std::stoi(year_str);
std::cout << year + 1 << "\n"; // 1998
std::string price_str = "9.99";
double price = std::stod(price_str);
int track = 7;
std::string label = "Track " + std::to_string(track);
std::cout << label << "\n"; // Track 7std::stoi— string to intstd::stod— string to doublestd::to_string— any number to string
Trap: std::stoi("abc") throws an exception and crashes your program unless you handle it. Exception handling is coming in chapter 11.
11. Try It — Live Demo (4 min)
#include <iostream>
#include <string>
int main()
{
std::string song = "Bailamos";
std::cout << song << " has " << song.size() << " characters\n";
song += ", mi amor";
std::cout << song << "\n";
size_t pos = song.find("mi");
if (pos != std::string::npos) {
std::cout << "found 'mi' at position " << pos << "\n";
}
std::cout << "first word: " << song.substr(0, 8) << "\n";
return 0;
}Ask the class to predict song.size() after the +=. Then run it.
12. Wrap-up Quiz Questions (3 min)
Q1. What does this print?
std::string a = "Ice";
std::string b = a + " " + a + " Baby";
std::cout << b.size() << "\n";A. 8 B. 11 C. 12 D. 13 E. Ben got this wrong
Answer: C — "Ice Ice Baby" is 12 characters including the spaces.
Q2. Where is the bug?
std::string greeting = "Hello, " + "world!";A. Missing #include <string> B. std::string does not allow + C. Both operands are string literals — at least one side must be a std::string D. + requires += instead E. Ben got this wrong
Answer: C
Q3. After std::cin >> age;, you call std::getline(std::cin, name); and name comes back empty. Why?
A. std::getline only reads one word B. The newline left by >> was consumed by getline C. std::cin was closed D. std::getline does not work with std::string E. Ben got this wrong
Answer: B — fix with std::cin.ignore().
13. Assignment / Reading (1 min)
- Read: chapter 4 of Gorgo Starting C++
- Do: all 9 exercises at the end of chapter 4
- Bring: next time we will build expressions from strings and numbers together
Key Points to Reinforce
std::stringlives in<string>— always include it.size()/.length()are equal; both returnsize_t- Concatenation with
+requires at least onestd::stringoperand ==,<, etc. compare by ASCII value, character by character[]is fast,.at()is safe — know which you needstd::getlinereads full lines; watch out for leftover newlines after>>std::stoi,std::stod,std::to_stringbridge strings and numbers