Как читать целочисленный ввод от пользователя в Rust 1.0?
Существующие ответы, которые я нашел, основаны на from_str
(например, Чтение в пользовательском входе с консоли один раз эффективно), но, по-видимому, from_str(x)
изменился в x.parse()
в Rust 1.0. Как новичок, не очевидно, как оригинальное решение должно быть адаптировано с учетом этого изменения.
Как и в Rust 1.0, какой самый простой способ получить целочисленный ввод от пользователя?
Ответы
Ответ 1
Вот версия со всеми дополнительными аннотациями типов и обработкой ошибок, которая может быть полезна для начинающих, таких как я:
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),
};
}
Ответ 2
Вероятно, проще всего было бы использовать text_io crate и написать:
#[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);
}
Если вам нужно прочитать более одного значения одновременно, вам может понадобиться использовать Rust по ночам.
Смотрите также:
Ответ 3
Вот несколько возможностей (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);
}
}
Это избавит вас от церемонии сопоставления шаблонов, в зависимости от дополнительных библиотек.
Ответ 4
parse
более или менее одинаковый; его read_line
теперь неприятно.
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."),
}
}
Ответ 5
Если вы ищете способ прочитать ввод для целей конкурентного программирования на веб-сайтах, таких как codechef или codeforces, где у вас нет доступа к text_io
.
Это не новый способ чтения, а упомянутый в ответах выше, я просто изменил его в соответствии со своими потребностями.
Я использую следующий макрос для чтения из stdin различных значений:
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>>();
};
}
В основном
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);
}
ПРИМЕЧАНИЕ: я не эксперт по ржавчине, если вы думаете, что есть способ улучшить его, пожалуйста, дайте мне знать. Это поможет мне, спасибо.
Ответ 6
Вы можете создать метод расширения, если вы хотите простой синтаксис:
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(())
}