Sundar R
Sundar R

Reputation: 14695

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

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) has changed into x.parse() in Rust 1.0. As a newbie, it's not obvious how the original solution should be adapted taking this change into account.

As of Rust 1.0, what is the easiest way to get an integer input from the user?

Upvotes: 40

Views: 57690

Answers (8)

Michael
Michael

Reputation: 5062

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::<i32>() {
        Ok(i) => println!("your integer input: {}", i),
        Err(..) => println!("input is not an integer: {}", trimmed),
    };
}

Upvotes: 74

coder3101
coder3101

Reputation: 4165

If you are looking for a way to read input for the purpose of competitive programming on websites like codeforces where you do not have access to text_io, this solution is for you.

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


#[allow(unused_macros)]
macro_rules! read {
    ($out:ident as $type:ty) => {
        let mut inner = String::new();
        std::io::stdin().read_line(&mut inner).expect("A String");
        let $out = inner.trim().parse::<$type>().expect("Parsable");
    };
}

#[allow(unused_macros)]
macro_rules! read_str {
    ($out:ident) => {
        let mut inner = String::new();
        std::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();
        std::io::stdin().read_line(&mut inner).unwrap();
        let $out = inner
            .trim()
            .split_whitespace()
            .map(|s| s.parse::<$type>().unwrap())
            .collect::<Vec<$type>>();
    };
}
  

Use it as follows:


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);
}

Upvotes: 25

Ruman
Ruman

Reputation: 1044

you can try this piece of code

fn main() {

    let mut line  = String::new();

    // read input line string and store it into line
    std::io::stdin().read_line(&mut line).unwrap();

    // convert line to integer
    let number : i32 = line.trim().parse().unwrap();

    println!("Your number {}",number);
}

now you can write a function for taking user input and use it everytime like below

fn main() {

    let first_number = get_input();
    let second_number = get_input();

    println!("Summation : {}",first_number+second_number);

}

fn get_input() -> i32{

    let mut line  = String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    let number : i32 = line.trim().parse().unwrap();
    return number ;
}

Upvotes: 2

user5683940
user5683940

Reputation:

I would definitely use the file system Rust-Lang provides std::fs (See more here: https://doc.rust-lang.org/stable/std/fs/) But more particularly https://doc.rust-lang.org/stable/std/fs/fn.read_to_string.html

Let's say you just want to read input of a text file, try this :

use std::fs
or
use std::fs::read_to_string

fn main() {
    println!("{}", fs::read_to_string("input.txt"));   
}

Upvotes: 2

Daniel Fath
Daniel Fath

Reputation: 18069

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:

Upvotes: 15

Boiethios
Boiethios

Reputation: 42749

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(())
}

Upvotes: 3

qed
qed

Reputation: 23104

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.

Upvotes: 14

Ry-
Ry-

Reputation: 224886

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."),
    }
}

Upvotes: 4

Related Questions