How to read an integer input from the user in Rust 1.0?

后端 未结 7 1945
栀梦
栀梦 2020-11-30 11:08

Existing answers I\'ve found are all based on from_str (such as Reading in user input from console once efficiently), but apparently from_str(x) h

相关标签:
7条回答
  • 2020-11-30 11:26

    If you are looking for a way to read input for the purpose of competitive programming in websites like codechef or codeforces where you do not have access to text_io.

    This is not a new way to read rather one mentioned in the above answers, I just modified it to suit my needs.

    I use the following macro to read from stdin the different values:

    use std::io;
    
    #[allow(unused_macros)]
    macro_rules! read {
        ($out:ident as $type:ty) => {
            let mut inner = String::new();
            io::stdin().read_line(&mut inner).expect("A String");
            let $out = inner.trim().parse::<$type>().expect("Parseble");
        };
    }
    
    #[allow(unused_macros)]
    macro_rules! read_str {
        ($out:ident) => {
            let mut inner = String::new();
            io::stdin().read_line(&mut inner).expect("A String");
            let $out = inner.trim();
        };
    }
    
    #[allow(unused_macros)]
    macro_rules! read_vec {
        ($out:ident as $type:ty) => {
            let mut inner = String::new();
            io::stdin().read_line(&mut inner).unwrap();
            let $out = inner
                .trim()
                .split_whitespace()
                .map(|s| s.parse::<$type>().unwrap())
                .collect::<Vec<$type>>();
        };
    }
    
    

    In main

    
    fn main(){
       read!(x as u32);
       read!(y as f64);
       read!(z as char);
       println!("{} {} {}", x, y, z);
    
       read_vec!(v as u32); // Reads space separated integers and stops when newline is encountered.
       println!("{:?}", v);
    }
    
    

    NOTE: I am no Rust Expert, if you think there is a way to improve it, please let me know. It will help me, Thanks.

    0 讨论(0)
  • 2020-11-30 11:29

    Probably the easiest part would be to use the text_io crate and write:

    #[macro_use]
    extern crate text_io;
    
    fn main() {
        // read until a whitespace and try to convert what was read into an i32
        let i: i32 = read!();
        println!("Read in: {}", i);
    }
    

    If you need to read more than one value simultaneously, you might need to use Rust nightly.

    See also:

    • Is there a way to check that the user entered an integer with text_io's read!() macro?
    0 讨论(0)
  • 2020-11-30 11:32

    Here are a few possibilities (Rust 1.7):

    use std::io;
    
    fn main() {
        let mut n = String::new();
        io::stdin()
            .read_line(&mut n)
            .expect("failed to read input.");
        let n: i32 = n.trim().parse().expect("invalid input");
        println!("{:?}", n);
    
        let mut n = String::new();
        io::stdin()
            .read_line(&mut n)
            .expect("failed to read input.");
        let n = n.trim().parse::<i32>().expect("invalid input");
        println!("{:?}", n);
    
        let mut n = String::new();
        io::stdin()
            .read_line(&mut n)
            .expect("failed to read input.");
        if let Ok(n) = n.trim().parse::<i32>() {
            println!("{:?}", n);
        }
    }
    

    These spare you the ceremony of pattern matching without depending on extra libraries.

    0 讨论(0)
  • 2020-11-30 11:32

    parse is more or less the same; it’s read_line that’s unpleasant now.

    use std::io;
    
    fn main() {
        let mut s = String::new();
        io::stdin().read_line(&mut s).unwrap();
    
        match s.trim_right().parse::<i32>() {
            Ok(i) => println!("{} + 5 = {}", i, i + 5),
            Err(_) => println!("Invalid number."),
        }
    }
    
    0 讨论(0)
  • 2020-11-30 11:39

    You can create an extension method if you want a simple syntax:

    use std::error::Error;
    use std::io;
    use std::str::FromStr;
    
    trait Input {
        fn my_read<T>(&mut self) -> io::Result<T>
        where
            T: FromStr,
            T::Err: Error + Send + Sync + 'static;
    }
    
    impl<R> Input for R where R: io::Read {
        fn my_read<T>(&mut self) -> io::Result<T>
        where
            T: FromStr,
            T::Err: Error + Send + Sync + 'static,
        {
            let mut buff = String::new();
            self.read_to_string(&mut buff)?;
    
            buff.trim()
                .parse()
                .map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))
        }
    }
    
    // Usage:
    
    fn main() -> io::Result<()> {
        let input: i32 = io::stdin().my_read()?;
    
        println!("{}", input);
    
        Ok(())
    }
    
    0 讨论(0)
  • 2020-11-30 11:47

    Here is a version with all optional type annotations and error handling which may be useful for beginners like me:

    use std::io;
    
    fn main() {
        let mut input_text = String::new();
        io::stdin()
            .read_line(&mut input_text)
            .expect("failed to read from stdin");
    
        let trimmed = input_text.trim();
        match trimmed.parse::<u32>() {
            Ok(i) => println!("your integer input: {}", i),
            Err(..) => println!("this was not an integer: {}", trimmed),
        };
    }
    
    0 讨论(0)
提交回复
热议问题