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
- Provide enough lines on stdin to answer every prompt interactively expected by the game.
- Run the program in an interactive terminal instead of piping a too-short stream.
- 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
- Use match on read_line's Result instead of .expect for user-facing input.
- When piping input, supply one line per prompt.
- Test stdin-exhaustion paths explicitly in CI.
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.