我最近学习了如何使用Rust文档中的io
读取输入,但是有没有' 简单'读取控制台输入的方法?我的根源是大量挖掘C ++,因此从控制台获取输入就像std::cin >> var
一样简单。但在Rust,我正在做:
for line in io::stdin().lines() {
print!("{}", line.unwrap());
break;
}
这会读取一次输入,但for循环似乎是一种非常笨拙的方法来实现这一点。我怎么能轻易做到这一点?
答案 0 :(得分:6)
std::io::stdin()
返回BufferedReader<StdReader>
,BufferedReader
实现Buffer
特征。这意味着您可以在其上调用read_line()
方法:
match io::stdin().read_line() {
Ok(line) => // do whatever you want, line is String
Err(e) => // handle error, e is IoError
}
如果您想阅读多行,最好先将io::stdin()
结果保存到变量中。
答案 1 :(得分:5)
io::stdin()
实际上是BufferedReader<>
包裹stdin
。正如您所见in the docs,BufferedReader
提供了很多提取内容的方法。
你特别注意:
fn read_line(&mut self) -> IoResult<String>
将尝试从stdin读取一行(并可能返回错误)。从stdin读取int
的简单代码是:
let a: int = from_str(io::stdin().read_line().unwrap().as_slice()).unwrap()
但它没有任何错误处理,很容易失败。
更明确的方法需要你更干净地处理事情:
let a: int = match from_str(
match io::stdin().read_line() {
Ok(txt) => txt, // Return the slice from_str(...) expects
Err(e) => { /* there was an I/O Error, details are in e */ }
}.as_slice() ) /* match from_str(...) */ {
Some(i) => i, // return the int to be stored in a
None => { /* user input could not be parsed as an int */ }
};
答案 2 :(得分:3)
正如@freinn正确指出的那样,以上答案现在已过时。从Rust 1.0开始,read_line()
要求调用者传递一个缓冲区,而不是函数创建并返回一个缓冲区。以下代码需要Rust 1.26+(进一步简化错误处理)。
请注意,使用trim_end()
修剪了响应。这样可以确保用户输入的换行符也不会成为响应的一部分,这会将问候分为两行。
还请注意,在用户不提供响应的情况下,以下示例是可靠的:
use std::error::Error as StdError;
use std::io::stdin;
use std::result::Result as StdResult;
type Result<T> = StdResult<T, Box<StdError>>;
fn main() -> Result<()> {
println!("Hello, there! What is your name?");
let buffer = &mut String::new();
stdin().read_line(buffer)?; // <- API requires buffer param as of Rust 1.0; returns `Result` of bytes read
let res = match buffer.trim_end() {
"" => "Ah, well I can respect your wish to remain anonymous.".to_owned(),
name => format!("Hello, {}. Nice to meet you!", name),
};
println!("{}", res);
Ok(())
}