已经存在的答案都是基于 from_str
的(比如 高效地从控制台读取用户输入),但显然在 Rust 1.0 中 from_str(x)
已经改变成了 x.parse()
。对于新手而言,不清楚原始解决方案应该如何适应这个变化。
截至 Rust 1.0,从用户那里获取整数输入的最简单方法是什么?
已经存在的答案都是基于 from_str
的(比如 高效地从控制台读取用户输入),但显然在 Rust 1.0 中 from_str(x)
已经改变成了 x.parse()
。对于新手而言,不清楚原始解决方案应该如何适应这个变化。
截至 Rust 1.0,从用户那里获取整数输入的最简单方法是什么?
这是一个带有所有可选类型注释和错误处理的版本,对像我这样的初学者可能很有用:
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),
};
}
如果您想在像 Codeforces 这样的网站上进行竞技编程,但无法访问 text_io
,那么这个解决方案就适用于您。
我使用以下宏从 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>>();
};
}
使用方法如下:
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);
}
可能最容易的部分是使用text_io包并编写:
#[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 nightly 版本。
参见:
text_io
的开发者。@VladimirMatveev 是正确的,如果你只读取单个值而不是元组,那么 text_io
可以在稳定版上运行。实际上,要读取多个值需要使用 nightly 版本。我会更新 Github 描述。 - oli_obktext_io
建议很好,但是在使用read!()
之前无法从函数中打印语句。 - JosephTLyonsread!()
之前从函数中打印语句"? - Daniel Fathtext_io
的read!()
之前使用println!()
,那么应该从println!()
打印的项目直到read!()
方法之后才被打印。 - JosephTLyons以下是一些可能性(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);
}
}
这些可以帮助你避免使用额外的库而不需要进行模式匹配的繁琐过程。
Option::expect
而不是match
可以更简洁并在错误情况下失败”的评论。 “完整的答案使读者更容易理解” - 这个答案缺少所需的use std::io
和fn main
,这是被接受的答案所具备的,对于真正的初学者来说这是必要的。 - Shepmasterparse
差不多是一样的;现在不好处理的是 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."),
}
}
如果您想要简单的语法,可以创建扩展方法:
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(())
}
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);
}
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 ;
}
我肯定会使用Rust-Lang提供的文件系统std::fs
(在此处查看更多信息:https://doc.rust-lang.org/stable/std/fs/),但更具体地说是https://doc.rust-lang.org/stable/std/fs/fn.read_to_string.html
假设您只想读取文本文件的输入,请尝试以下操作:
use std::fs
or
use std::fs::read_to_string
fn main() {
println!("{}", fs::read_to_string("input.txt"));
}
parse()
产生的Result
与match
来报告的。unwrap()
会导致程序崩溃。 - raindevcin >> i
有很大不同。 - ynn