Word boundaries and reliable text tests
Remember whether you are inside a word, then use small boundary cases to audit a scan.
Define a word before counting one
Here a word is a maximal consecutive group of non-space characters. Only the ordinary space character separates words; tabs are outside this exercise’s format. Repeated, leading, and trailing spaces do not create extra words.
Counting spaces and adding one fails on an empty line or repeated spaces. Instead, count transitions into a word. Start insideWord as false. A space sets it false; a non-space while outside increments the count and sets it true.
#include <iostream>
#include <string>
int main() {
std::string line;
std::getline(std::cin, line);
int words = 0;
bool insideWord = false;
int n = static_cast<int>(line.size());
for (int i = 0; i < n; ++i) {
if (line[i] == ' ') {
insideWord = false;
} else if (!insideWord) {
++words;
insideWord = true;
}
}
std::cout << words << '\n';
return 0;
}A neighbour rule describes the same event
Index i begins a word exactly when line[i] is not a space and either i == 0 or line[i − 1] is a space. The short-circuit order ensures that index −1 is never accessed.
The state-flag solution remembers the previous situation, while the neighbour solution reads it from the sequence. Both count starts, not every non-space character. Both scan the line once.
Draw the smallest failing sequence
For an array or string failure, write the active length and every valid index. Calculate i − 1, i + 1, and n − 1 − i explicitly. A program that does not crash can still access invalid or inactive cells.
Test empty input when allowed, one character, repeated characters, a match at index zero, a missing target, and leading or repeated spaces. For arrays, include all-negative extrema and tied maxima. For matrices, include odd/even dimensions and nonsquare shapes.
Compile with C++23 and warnings. Where supported, address and undefined-behavior sanitizers can expose invalid operations on executed paths, but do not replace reasoning about bounds. A warning about signed and unsigned sizes deserves an explanation, not a random cast.
How many words are in a line containing two spaces, we, two spaces, learn, one space, C++, and two trailing spaces?
Turn the idea into code
Reimplement word counting with the neighbour rule, without an insideWord flag. Empty lines are allowed; lines contain only ordinary spaces and other ASCII non-space characters.
Give me a hint
A word begins at a non-space whose predecessor does not exist or is a space.
Show the explained solution
The i == 0 part must come first within the OR, so the previous-character access is skipped at the start. An empty or all-space line contributes no word starts.
#include <iostream>
#include <string>
int main() {
std::string line;
std::getline(std::cin, line);
int words = 0;
int n = static_cast<int>(line.size());
for (int i = 0; i < n; ++i) {
if (line[i] != ' ' && (i == 0 || line[i - 1] == ' ')) {
++words;
}
}
std::cout << words << '\n';
return 0;
}Your notes
Mark complete when you can explain it yourself.