Loop control, input validation, and dry runs
Control loop execution with break and continue, validate user input, and manually trace iterations before running code.
Learning objectives
- Distinguish
break(exit the nearest loop) fromcontinue(skip to the next iteration). - Validate an entire input line rather than accepting a valid numeric prefix.
- Trace a loop with a table and predict its final state.
- Spot infinite-loop and off-by-one risks before running a program.
Prerequisites: for and while loops, conditions, and basic input/output. Review Loops, Conditions, and Input and output.
break exits the nearest loop
break immediately terminates the nearest enclosing loop or switch. Control continues with the first statement after that construct; a break in an inner loop does not automatically exit an outer loop.
for (int number = 1; number <= 5; ++number) {
if (number == 4) break;
std::cout << number << ' ';
}
// output: 1 2 3
continue skips the rest of one iteration
continue skips the remaining statements in the current iteration. In a for loop, the iteration expression still runs before the next condition check.
for (int number = 1; number <= 5; ++number) {
if (number == 3) continue;
std::cout << number << ' ';
}
// output: 1 2 4 5
Validate a complete input line
Formatted extraction such as std::cin >> choice can successfully read a numeric prefix from a line like 2abc. For a menu that should accept exactly one integer per line, read the line first and parse it separately. This example rejects non-numeric input, extra tokens, and out-of-range choices; it also handles end-of-file without retrying forever.
#include <iostream>
#include <sstream>
#include <string>
int main() {
int choice{};
while (true) {
std::cout << "Choose 1, 2, or 3: ";
std::string line;
if (!std::getline(std::cin, line)) {
std::cout << "\nInput ended.\n";
return 0;
}
std::istringstream input{line};
std::string extra;
if (!(input >> choice) || (input >> extra)) {
std::cout << "Enter exactly one whole number.\n";
continue;
}
if (choice >= 1 && choice <= 3) {
break;
}
std::cout << "Choice must be from 1 to 3.\n";
}
std::cout << "Accepted: " << choice << '\n';
}For input lines hello, 2abc, 7, and 2, the program rejects the first three lines and accepts the last. getline consumes each whole line, so the next attempt starts at the next line.
Dry-run with a trace table
A dry run means manually following the statements without executing the program. Record the state after each iteration and include skipped statements explicitly.
int total{0};
for (int i = 1; i <= 4; ++i) {
if (i == 2) continue;
total += i;
}i | Action | total after iteration |
|---|---|---|
| 1 | Add 1 | 1 |
| 2 | Skip addition; then update i | 1 |
| 3 | Add 3 | 4 |
| 4 | Add 4 | 8 |
After the fourth iteration, i becomes 5; the condition is false and the loop ends. The final total is 8.
Common loop bugs
- Off by one: for zero-based positions, use
i < sizeso the last valid index issize - 1. - No progress: update state that affects the loop condition or provide a deliberate exit.
- Incorrect continue trace: remember that a
forloop still performs its iteration expression aftercontinue. - Unrecoverable input state: after failed formatted extraction, clear the stream state and discard invalid characters—or use line-based parsing as shown.
Practice
- Use
continueto print only odd numbers from 1 through 9. - Dry-run
int s=0; for(int i=0;i<5;++i) { if(i==3) break; s+=i; }. Finds. - Why should a menu that accepts one integer reject the line
2abc? - What should a retry loop do when input reaches end-of-file?
Worked answers
Show reasoned answers
- Continue when
number % 2 == 0; print the other values. Output:1 3 5 7 9. - It adds 0, 1, and 2. At
i == 3, break runs before addition, sos == 3. - Because formatted integer extraction can read the valid prefix
2and leaveabcunread; whole-line validation rejects trailing non-whitespace input. - Stop or return from the input routine; retrying after EOF without a policy can create an endless prompt loop.
Summary
Use break to exit the nearest loop, continue to skip one iteration, and a trace table to make state changes visible. Validate the complete input unit and handle EOF deliberately.