My first program in Rust is supposed to take input from the user in the form of characters, either C or F:
use std::io;
fn main() {
let mut srcunit = String::new();
let mut switch = true;
while switch {
println!("source unit? F or C?");
io::stdin().read_line(&mut srcunit).expect(
"failed to read src unit",
);
if srcunit.trim() == "F" || srcunit.trim() == "C" {
println!("doing things right with {}", srcunit);
switch = false;
} else {
println!("either F or C, not {}", srcunit);
}
}
println!("you pressed {}", srcunit);
}
When I start the program and press either F or C, it works right, so I'm skipping this here. The weird part comes when I press another character. I expect my program to ask again for either F or C until I press one of those characters. When I do, it should leave the while loop and tell me what I've pressed.
source unit? F or C?
G
either F or C, not G //so far so good
source unit? F or C?
F
either F or C, not G //why is F not assigned to the srcunit variable? It's supposed to leave the loop now.
F //why does it print this line? I didn't press a key or have a println function/macro that does this
source unit? F or C?
V
either F or C, not G //it's still G, wtf
F //again, why are those two lines printed? Where does it store, that I pressed F previously?
V
From the documentation for
read_line
:(Emphasis mine.) You need to clear the string before reading the next line, for example by calling the
clear()
method on the string, otherwise the answers are accumulated in the variable.Alternatively, you can define the variable in the loop (but this is slightly less efficient because this way,
String
will not be able to reuse the already allocated storage for the next answer, it has to be deallocated and reallocated again).See also this question, asked recently. Looks like this is a common trap.