Reputation: 14695
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
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
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
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
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
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
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
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
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