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

  1. 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
  2. Use match to detect Ok(0) (EOF) and break the inner guess loop
  3. 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

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


AI-assisted analysis of coding-horror/basic-computer-games@5301155192 (2026-08-13). Data as JSON: /api/errors/721716e466dae9b5. Report an issue: GitHub.