The problem: print!()
doesn't flush stdout!
What does flushing mean, you ask? When printing, you don't want to send every character to stdout on its own: this would occur a lot of overhead (think: doing a syscall, the terminal would have to update its view, ...). So instead of doing that, there is exists a buffer somewhere which holds the content which is about to be printed. To actually print, this buffer has to be flushed.
The reason you hardly notice all of this is, that stdout is always flushed when a newline ('\n'
) is printed. Thus, println!()
always flushes!
Your use case is even more confusing, because you are typing into stdin. Here it works pretty much the same way: when you type, the characters are not yet send anywhere! Only the terminal/shell stores what you typed. But once you hit enter (newline), your written text is submitted and send to stdin.
Anyway, you can manually flush stdout without printing a newline:
use std::io::{self, BufRead, Write};
fn main() {
println!("Usage instructions and stuff");
print!("Command:");
io::stdout().flush().expect("Couldn't flush stdout"); // <-- here
let stdin = io::stdin();
let mut line = String::new();
stdin.lock().read_line(&mut line).expect("Couldn't process the command.");
println!("{}", line);
}
This behavior was criticized before: "print! should flush stdout".
And please note: your string line
contains a newline character at the very end. You can remove it with trim_right(). This has nothing to do with your original question, but you are likely to run into this problem as well ;-)