coding-horror/basic-computer-games · error
Failed to read the line
Error message
Failed to read the line
What it means
In 47_Hi-Lo, inside a loop of up to 6 guesses, the game reads the player's numeric guess via io::stdin().read_line(&mut guess).expect("Failed to read the line"). Non-numeric input is handled gracefully by a match on guess.trim().parse() that prints 'PLEASE ENTER A NUMBER VALUE' and continues the loop. The .expect() guards only the I/O layer.
Source
Thrown at 47_Hi-Lo/rust/src/main.rs:26
);
println!("THIS IS THE GAME OF HI LO.\n");
println!("YOU WILL HAVE 6 TRIES TO GUESS THE AMOUNT OF MONEY IN THE");
println!("HI LO JACKPOT, WHICH IS BETWEEN 1 AND 100 DOLLARS. IF YOU");
println!("GUESS THE AMOUNT, YOU WIN ALL THE MONEY IN THE JACKPOT!");
println!("THEN YOU GET ANOTHER CHANCE TO WIN MORE MONEY. HOWEVER,");
println!("IF YOU DO NOT GUESS THE AMOUNT, THE GAME ENDS.\n");
let mut total: u32 = 0;
loop {
let jackpot_amount = rand::thread_rng().gen_range(1..101); // generates a random number between 1 and 100
for i in 0..6 {
println!("YOUR GUESS?");
let mut guess = String::new();
io::stdin()
.read_line(&mut guess)
.expect("Failed to read the line");
// this converts the input string into unsigned 32bit number and if the input entered is not a number
// it will again prompt the user to enter the guess number
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => {
println!("PLEASE ENTER A NUMBER VALUE.\n");
continue;
}
};
// compare it with the jackpot amount
if guess == jackpot_amount {
println!("\nGOT IT!!!!!!!!!! YOU WIN {} DOLLARS.", jackpot_amount);
total += jackpot_amount;
println!("YOUR TOTAL WINNINGS ARE NOW {} DOLLARS.\n", total);
break;
} else if guess < jackpot_amount {View on GitHub (pinned to 5301155192)
Solutions
- Replace .expect() with .unwrap_or_default() so I/O failure yields an empty string, which the existing parse-failure path handles by printing the error and continuing
- Use match to detect Ok(0) (EOF) and break the inner guess loop
- Extract a read_guess helper that loops on parse errors but exits on I/O errors
Example fix
// before
let mut guess = String::new();
io::stdin()
.read_line(&mut guess)
.expect("Failed to read the line");
let guess: u32 = match guess.trim().parse() {
// after
let mut guess = String::new();
let _ = io::stdin().read_line(&mut guess);
let guess: u32 = match guess.trim().parse() { Defensive patterns
Strategy: fallback
Try / catch
let mut guess = String::new(); let _ = io::stdin().read_line(&mut guess); // empty string fails to parse as u32, triggering the // existing 'PLEASE ENTER A NUMBER VALUE' retry
Prevention
- For guess loops that already retry on parse failures, let I/O failures degrade to parse failures by using let _ = read_line(...)
- Do not use .expect() on reads inside retry loops — the loop's error path should handle all failure modes
- Test guess loops with input files that end mid-loop to verify graceful degradation
When it happens
Trigger: The player is prompted 'YOUR GUESS?' and stdin returns Err or EOF. Invalid numbers trigger the retry loop, but missing input (EOF) panics before the parse match runs.
Common situations: Piped input that runs out during the 6-guess loop, Ctrl+D at a guess prompt, or CI tests that provide fewer lines than the game expects.
Related errors
- Failed to read the line
- Error reading from stdin
- Error reading line.
- ~~Failed reading line!~~
- Failed to get Input
AI-assisted analysis of coding-horror/basic-computer-games@5301155192 (2026-08-13).
Data as JSON: /api/errors/721716e466dae9b5.
Report an issue: GitHub.