Why does this read input before printing?

前端 未结 3 1809
日久生厌
日久生厌 2020-11-27 08:34

I\'m having some problems with some basic I/O stuff. Specifically, the text \"Please enter your name\" is written to the output after I type in my name and

相关标签:
3条回答
  • 2020-11-27 08:55

    This is explained on the documentation for print!. Since print! does not emit a newline and stdout is line-buffered, you won't see any output. You can manually flush stdout:

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

    For your second question you can always return unit explicitly:

    Ok(_) => (),
    

    So your program becomes:

    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 pointed out in their (now deleted) comment, you can use an if let expression in place of the match on the result of read_line:

    if let Err(err) = io::stdin().read_line(&mut name) {
        println!("Could not parse input: {}", err)
    }
    
    0 讨论(0)
  • 2020-11-27 09:00

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

    Well, it did. It's just that, for performance reasons, standard output is buffered. The write completed, but it was only writing to memory. If you want it to actually display to the user, you have to trigger a flush. This can be done either by writing a newline, or by doing it 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 a 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 arms in a match have to have the same result type. In the case of println!, it results in a (); aside from an empty block (or another function that returns ()), you can just use a literal:

    match io::stdin().read_line(&mut name) {
        Ok(_) => (),
        Err(err) => println!("Could not parse input: {}", err)
    }
    
    0 讨论(0)
  • 2020-11-27 09:10
    use std::io::{self, Write};
    
    fn main() {
        print!("Please enter your name: ");
        let _ = io::stdout().flush();
        // your io code
    }
    
    0 讨论(0)
提交回复
热议问题