C++ · Strings
Strings
Trace the newline left after numeric cin input and use getline to read a full line with spaces, alongside character counts, palindromes, find and substr.
Practice this topic in the app Read the lesson in the app
String access and common operations
You can think of a string as a train: each car holds one letter, and the indices are numbered starting from 0. s[0] is the first car, s[1] is the second car……
There are two common ways in C++:
char s[100]: the old-style character array, with a'\0'terminator at the end, operated on with functions such asstrlen/strcmp/strcpy.string s: more convenient, supporting+concatenation,s.length()for length,s.substr()for substrings, ands.find()for searching.
Common practice tasks: counting characters, reversing strings, checking palindromes, finding substrings, and converting character case.
Common member functions: size()/length() returns the length, empty() checks whether the string is empty; substr(pos,len) takes a substring, find returns a position or string::npos; insert(pos,text) inserts, erase(pos,len) deletes, replace(pos,len,text) replaces. pos must be valid, and len is a length rather than an ending index. To read an entire line containing spaces, use getline; if a number was read before, handle the leftover newline first.
After cin, what is left for getline?
cin >> name reads one word and stops at whitespace. By default, getline(cin, name) reads through the next newline, preserving spaces within the line and consuming the newline. Assume the input format is an integer on the first line and a full name on the next: 3\nAda Lovelace\n. Here \n denotes a newline character.
| Operation | Remaining input | Value obtained |
|---|---|---|
| Start | 3\nAda Lovelace\n | Nothing read |
| cin >> n | \nAda Lovelace\n | n = 3 |
| Discard the rest of the first line, including its newline | Ada Lovelace\n | Name not read yet |
| getline(cin, name) | Empty | name = "Ada Lovelace" |
If getline follows the number immediately, it encounters the leftover newline and returns an empty string. It has not skipped the next line automatically. For this input format, after successful numeric extraction, use cin.ignore(numeric_limits<streamsize>::max(), '\n') to discard the remainder of the current line, then read the name. This discards any other characters on that line too, so it is unsuitable when the number and name share a line.
First common error: calling getline twice unconditionally can consume a line that should be kept. Second: treating getline(cin >> ws, name) as a universal fix. ws skips all leading whitespace, including blank lines and spaces at the start of a name. When those matter, handle only the current line according to the input format. The program below checks extraction success; recovering from invalid numeric input is a separate topic. Reading k text characters involves processing them, rather than fixed O(1) work.
Run and check: a number followed by a full line
#include <iostream>
#include <limits>
#include <string>
int main() {
int n;
std::string name;
if (!(std::cin >> n)) { return 0; }
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if (!std::getline(std::cin, name)) { return 0; }
std::cout << n << " [" << name << "]\n";
}Input two lines: 3 and Ada Lovelace. Output: 3 [Ada Lovelace]. Brackets make empty strings and preserved spaces visible.
Try before revealing each answer
Does ignoring through the newline still work if two spaces follow 3 on the first line?
Yes. The remaining spaces and newline on that line are discarded. Ignoring only one character can leave other whitespace behind.
If the next line starts with two spaces followed by Ada, does the example keep those spaces?
Yes. getline does not skip leading spaces on the next line. Applying ws first would discard them.
Can you use the same ignore step if the input is 3 Ada Lovelace on one line?
No: it would discard the name too. Establish the input format before deciding how to read the remaining text.
Character counts, palindromes and string edits
Example 1: Count the number of occurrences of each letter in a string
#include <iostream>
#include <string>
using namespace std;
int main() {
string s = "Hello World";
int cnt[26] = {0};
for (char c : s) {
if (c >= 'a' && c <= 'z') cnt[c - 'a']++;
if (c >= 'A' && c <= 'Z') cnt[c - 'A']++;
}
for (int i = 0; i < 26; i++) {
if (cnt[i] > 0)
cout << (char)('a' + i) << ": " << cnt[i] << endl;
}
return 0;
}Use c-'a' to convert a letter into an index from 0 to 25 and store it in an array, then traverse and output at the end. In "Hello World", d:1 e:1 h:1 l:3 o:2 r:1 w:1.
Example 2: Determine whether a string is a palindrome
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cin >> s;
int n = s.length();
bool ok = true;
for (int i = 0; i < n / 2; i++) {
if (s[i] != s[n - 1 - i]) {
ok = false;
break;
}
}
cout << (ok ? "YES" : "NO") << endl;
return 0;
}Input "racecar", n=7, compare s[0] with s[6], s[1] with s[5], s[2] with s[4], all are equal, output YES.
Example 3: Find, substring, insert, and delete
#include <iostream>
#include <string>
using namespace std;
int main() {
string s = "hello world";
auto pos = s.find("world");
if (pos != string::npos) s.replace(pos, 5, "C++");
s.insert(0, "Hi! "); s.erase(0, 4);
cout << s << " " << s.substr(0, 5) << endl;
}Output hello C++ hello. Only use the position after find succeeds; the 5 in replace is the number of characters to replace.
Tips
- string subscripts start from 0, the subscript of the last character is s.length()-1, and out-of-bounds access causes an error.
- Characters and integers can be converted to each other: 'a'+1 is 'b', and 'A' and 'a' differ by 32 (tolower/toupper can be used to convert case).
- cin >> s stops when it encounters a space; to read a whole line containing spaces, use getline(cin, s).
- When s.find("abc") cannot find it, it returns string::npos; you must check whether it is this special value to confirm whether it was found.
Prerequisites
Technical references
Scope note
This lesson is written by InfoCode and is not an official syllabus; the reference level is a site mapping and does not represent official levels, certification or eligibility. Practice records do not establish mastery or eligibility.
Reference level: GESP Level 3 (site mapping)