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() inside get_number_from_user_input() of the Blackjack Rust port, used to read numeric bets/choices within a min..max range. read_line returns Err only on I/O-level failure (closed stdin, EOF, broken pipe); out-of-range or non-numeric input is handled by the parse branch with a re-prompt. The expect aborts on any read error.
Source
Thrown at 10_Blackjack/rust/src/main.rs:573
PRESS ENTER TO CONTINUE
");
io::stdin().read_line(&mut String::new()).expect("Failed to read line");
}
/**
* gets a usize integer from user input
*/
fn get_number_from_user_input(prompt: &str, min:usize, max:usize) -> usize {
//input loop
return loop {
let mut raw_input = String::new(); // temporary variable for user input that can be parsed later
//print prompt
println!("{}", prompt);
stdout().flush().expect("Failed to flush to stdout.");
//read user input from standard input, and store it to raw_input
//raw_input.clear(); //clear input
io::stdin().read_line(&mut raw_input).expect( "CANNOT READ INPUT!");
//from input, try to read a number
match raw_input.trim().parse::<usize>() {
Ok(i) => {
if i < min || i > max { //input out of desired range
println!("INPUT OUT OF VALID RANGE. TRY AGAIN. {}-{}",min,max);
continue; // run the loop again
}
else {
break i;// this escapes the loop, returning i
}
},
Err(e) => {
println!("INVALID INPUT. TRY AGAIN. {}", e.to_string().to_uppercase());
continue; // run the loop again
}
};
};View on GitHub (pinned to 5301155192)
Solutions
- Provide a numeric line within the valid range for every prompt in piped input.
- Run interactively so stdin remains open.
- Swap .expect for `match` that exits or returns a default on read error.
Example fix
// before
io::stdin().read_line(&mut raw_input).expect("CANNOT READ INPUT!");
// after
if io::stdin().read_line(&mut raw_input).is_err() {
println!("\nInput unavailable. Exiting.");
std::process::exit(1);
} Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure stdin is open before prompting; provide one in-range numeric line per call when piping.
Try / catch
// Replace .expect with a match
match io::stdin().read_line(&mut raw_input) {
Ok(_) => { /* parse usize in [min,max] */ }
Err(_) | Ok(0) => { println!("Input closed. Exiting."); std::process::exit(1); }
} Prevention
- Match read_line's Result instead of .expect for interactive input.
- Size piped input to cover every prompt with in-range values.
- Treat Ok(0) as EOF and exit cleanly.
When it happens
Trigger: stdin closed or exhausted before a numeric prompt is answered; redirected input that ends mid-game; broken pipe to stdin.
Common situations: Test/CI runs whose input fixture runs out of lines; piping /dev/null; a feeder script that closes stdin after a fixed count.
Related errors
AI-assisted analysis of coding-horror/basic-computer-games@5301155192 (2026-08-13).
Data as JSON: /api/errors/24bb3edc25bdddd2.
Report an issue: GitHub.