Why does it read input before printing?

I am having some problems with some basic input / output materials. In particular, the text "Please enter your name" is written in the output after . I type in my name and press Enter :

use std::io; fn main() { print!("Please enter your name: "); let mut name = String::new(); match io::stdin().read_line(&mut name) { Ok(_) => println!(""), Err(err) => println!("Could not parse input: {}", err) } println!("Hello, {}!", name.trim()); } 

gives the following result:

 Compiling chat v0.1.0 (file:///home/marcus/dev/rust/chat) Running `target/debug/chat` marcus Please enter your name: Hello, marcus! 

Where the first "Marcus" was introduced by me. Why won't the program print "Please enter your name" before waiting for input?


Is it possible to "do nothing" if the returned Result is Ok ? In the example, Ok() means that I saved the input in the variable name. It's great. But what should I do with Ok() => in this case?

+5
source share
2 answers

Why won't the program print "Please enter your name" before waiting for input?

Well yes. That's right, for performance reasons, standard output is buffered. Recording is completed, but it was recorded only in memory. If you want it to actually be displayed to the user, you need to call a flash. This can be done either by writing a new line or by explicitly:

 io::Write::flush(&mut io::stdout()).expect("flush failed!"); // If you "use" `io::Write`... io::stdout().flush().expect("flush failed!"); 

Also, is it possible to β€œdo nothing” if the returned result is β€œOK”?

Sure. Just ... do nothing.

 match io::stdin().read_line(&mut name) { Ok(_) => { /* nothing */ }, Err(err) => println!("Could not parse input: {}", err) } 

The relevant requirement here is that all hands in match must have the same type of result. In the case of println! this leads to a () ; besides an empty block (or another function returning () ), you can just use a literal:

 match io::stdin().read_line(&mut name) { Ok(_) => (), Err(err) => println!("Could not parse input: {}", err) } 
+8
source

This is explained in the documentation for print! . Since print! does not emit a new line, and stdout is buffered by line, you will not see any output. You can manually reset stdout:

 use std::io::{self, Write}; print!("Please enter your name: "); io::stdout().flush(); 

For your second question, you can always return the module explicitly:

 Ok(_) => (), 

So your program will be:

 use std::io::{self, Write}; fn main() { print!("Please enter your name: "); io::stdout().flush(); let mut name = String::new(); match io::stdin().read_line(&mut name) { Ok(_) => (), Err(err) => println!("Could not parse input: {}", err) } println!("Hello, {}!", name.trim()); } 

As @Veedrac noted in his (now deleted) comment, you can use if let expression instead of match on the result of read_line :

 if let Err(err) = io::stdin().read_line(&mut name) { println!("Could not parse input: {}", err) } 
+11
source

Source: https://habr.com/ru/post/1241414/


All Articles