coding-horror/basic-computer-games · error

CANNOT READ INPUT!

Error message

CANNOT READ INPUT!

What it means

A panic via .expect("CANNOT READ INPUT!") on io::stdin().read_line() in get_bet() of the Acey Ducey Rust port. read_line returns Err only when stdin itself is unavailable/closed (EOF on a closed pipe, redirected input exhausted, or a broken pipe), not on malformed text. The expect turns any such I/O failure into an immediate process abort.

Source

Thrown at 01_Acey_Ducey/rust/src/main.rs:121

    println!("CREATIVE COMPUTING - MORRISTOWN, NEW JERSEY");
    println!("ACEY-DUCEY IS PLAYED IN THE FOLLOWING MANNER");
    println!("THE DEALER (COMPUTER) DEALS TWO CARDS FACE UP");
    println!("YOU HAVE AN OPTION TO BET OR NOT BET DEPENDING");
    println!("ON WHETHER OR NOT YOU FEEL THE CARD WILL HAVE");
    println!("A VALUE BETWEEN THE FIRST TWO.");
    println!("IF YOU DO NOT WANT TO BET IN A ROUND, ENTER 0");
    println!("\n\n");
}

fn get_bet(user_bank: u16) -> u16 {
    loop {
        println!("\nWHAT IS YOUR BET? ENTER 0 IF YOU DON'T WANT TO BET (CTRL+C TO EXIT)");
        let bet: u16;
        let mut input = String::new();

        io::stdin()
            .read_line(&mut input)
            .expect("CANNOT READ INPUT!");

        match input.trim().parse::<u16>() {
            Ok(i) => bet = i,
            Err(e) => {
                println!("CHECK YOUR INPUT! {}!", e.to_string().to_uppercase());
                continue;
            }
        };

        match bet {
            bet if bet <= user_bank => return bet,
            _ => {
                println!("\nSORRY, MY FRIEND, BUT YOU BET TOO MUCH.");
                println!("YOU HAVE ONLY {} DOLLARS TO BET.", user_bank);
            }
        };
    }
}

View on GitHub (pinned to 5301155192)

Solutions

  1. Provide enough lines on stdin to answer every prompt interactively expected by the game.
  2. Run the program in an interactive terminal instead of piping a too-short stream.
  3. Replace .expect with graceful handling: match on the Result and exit cleanly on EOF.

Example fix

// before
io::stdin().read_line(&mut input).expect("CANNOT READ INPUT!");

// after: handle EOF gracefully
if io::stdin().read_line(&mut input).is_err() {
    println!("\nInput closed. Goodbye!");
    std::process::exit(0);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Rust: detect EOF/closed stdin before expecting a read
use std::io::IsTerminal;
if !std::io::stdin().is_terminal() {
    // ensure piped input has data; otherwise exit early
}

Try / catch

// Replace .expect with graceful handling
match io::stdin().read_line(&mut input) {
    Ok(_) => { /* parse bet */ }
    Err(_) => { println!("Input closed. Exiting."); std::process::exit(0); }
}

Prevention

When it happens

Trigger: Running the binary with stdin closed or redirected from an empty/exhausted file or pipe; piping input that ends before the bet prompt is answered; running under a harness that closes stdin early.

Common situations: Automated testing with insufficient piped input; running via `echo '' | ./game` where the stream ends; CI environments with no TTY and truncated input fixtures.

Related errors


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