std::string Operations
Length, indexing with .at, substr, find, concatenation, comparison โ and why .at beats [] while learning.
#include <string>
std::string s = "Code Journey";
The everyday operations
s.size() // 12 (length() is the same thing)
s[0] // 'C' โ NO bounds checking
s.at(0) // 'C' โ throws std::out_of_range if invalid
s.substr(5, 7) // "Journey" โ start index, count
s.find("Jour") // 5 โ index, or std::string::npos if absent
s + "!" // concatenation โ "Code Journey!"
s == "Code Journey" // true โ value comparison, not pointer comparison
.at() vs [] while you are learning
[] on a bad index is undefined behavior โ it may print garbage, crash, or silently corrupt memory. .at() throws a catchable exception. In this course's exercises, prefer .at(): when you inevitably go one step too far, you get a clear error instead of a mystery. (.at does cost a bounds check; professionals drop to [] in hot loops once logic is proven โ and say so in review.)
std::string::npos is the special "not found" value; compare with ==, never print it.
Characters
Indexing yields a char. Useful checks: std::isdigit, std::isalpha, std::isspace, std::toupper, std::tolower โ all take an int; pass static_cast<unsigned char>(c) (a plain char can be negative and that is UB). Ugly but correct โ the boilerplate does it, and now you know why.
Building strings
Prefer +/+= for small builds; for assembling many pieces (and numbers), std::ostringstream (next lesson) reads better than a pile of to_string calls.