如何从控制台有效地读取一行用户输入?

时间:2014-09-02 20:45:23

标签: rust

我最近学习了如何使用Rust文档中的io读取输入,但是有没有' 简单'读取控制台输入的方法?我的根源是大量挖掘C ++,因此从控制台获取输入就像std::cin >> var一样简单。但在Rust,我正在做:

for line in io::stdin().lines() {
    print!("{}", line.unwrap());
    break;
}

这会读取一次输入,但for循环似乎是一种非常笨拙的方法来实现这一点。我怎么能轻易做到这一点?

3 个答案:

答案 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 docsBufferedReader提供了很多提取内容的方法。

你特别注意:

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