How can I read a single line from stdin?

前端 未结 3 1594
南方客
南方客 2020-12-09 01:50

I\'m asking for the equivalent of fgets() in C.

let line = ...;
println!(\"You entered: {}\", line);

I\'ve read How to read us

相关标签:
3条回答
  • 2020-12-09 02:05

    In How to read user input in Rust? you can see how to iterate over all lines:

    use std::io::{self, BufRead};
    
    fn main() {
        let stdin = io::stdin();
        for line in stdin.lock().lines() {
            println!("{}", line.unwrap());
        }
    }
    

    You can also manually iterate without a for-loop:

    use std::io::{self, BufRead};
    
    fn main() {
        let stdin = io::stdin();
        let mut iterator = stdin.lock().lines();
        let line1 = iterator.next().unwrap().unwrap();
        let line2 = iterator.next().unwrap().unwrap();
    }
    

    You cannot write a one-liner to do what you want. But the following reads a single line (and is exactly the same answer as in How do I read a single String from standard input?):

    use std::io::{self, BufRead};
    
    fn main() {
        let stdin = io::stdin();
        let line1 = stdin.lock().lines().next().unwrap().unwrap();
    }
    

    You can also use the text_io crate for super simple input:

    #[macro_use] extern crate text_io;
    
    fn main() {
        // reads until a \n is encountered
        let line: String = read!("{}\n");
    }
    
    0 讨论(0)
  • 2020-12-09 02:10

    Read a single line from stdin:

        let mut line = String::new();
        std::io::stdin().read_line(&mut line)?; // including '\n'
    

    You may remove '\n' using line.trim_end()

    Read until EOF:

        let mut buffer = String::new();
        std::io::stdin().read_to_string(&mut buffer)?;
    

    Using implicit synchronization:

    use std::io;
    fn main() -> io::Result<()> {
        let mut line = String::new();
        io::stdin().read_line(&mut line)?;
    
        println!("You entered: {}", line);
        Ok(())
    }
    

    Using explicit synchronization:

    use std::io::{self, BufRead};
    
    fn main() -> io::Result<()> {
        let stdin = io::stdin();
        let mut handle = stdin.lock();
    
        let mut line = String::new();
        handle.read_line(&mut line)?;
    
        println!("You entered: {}", line);
        Ok(())
    }
    

    If you interested in the number of bytes e.g. n, use:
    let n = handle.read_line(&mut line)?;
    or
    let n = io::stdin().read_line(&mut line)?;

    Try this:

    use std::io;
    fn main() -> io::Result<()> {
        let mut line = String::new();
        let n = io::stdin().read_line(&mut line)?;
    
        println!("{} bytes read", n);
        println!("You entered: {}", line);
        Ok(())
    }
    

    See doc

    0 讨论(0)
  • 2020-12-09 02:12

    If you truly want the equivalent to fgets, then @Gerstmann is right, you should use Stdin::read_line. This method accepts a buffer that you have more control of to put the string into:

    use std::io::{self, BufRead};
    
    fn main() {
        let mut line = String::new();
        let stdin = io::stdin();
        stdin.lock().read_line(&mut line).unwrap();
        println!("{}", line)
    }
    

    Unlike C, you can't accidentally overrun the buffer; it will be automatically resized if the input string is too big.

    The answer from @oli_obk - ker is the idiomatic solution you will see most of the time. In it, the string is managed for you, and the interface is much cleaner.

    0 讨论(0)
提交回复
热议问题