如何从字符串中提取两个整数?

时间:2015-11-10 12:49:54

标签: input rust

如何从Rust的单行输入中提取两个i32?在Python中,我可以阅读两个int,如:

a, b = map(int, input().split()) #  "2 3"  =>  a=2 and b=3

从Rust 1.3.0开始,我可以运行以下内容来阅读一个i32:

let mut s = String::new();
std::io::stdin().read_line(&mut s).ok().expect("read_line panic");
let n: i32 = s.trim().parse().ok().expect("parse panic");

3 个答案:

答案 0 :(得分:8)

&str有一个split_whitespace()方法,它返回一个迭代器,产生目标字符串的一部分,由任意数量的空格分隔,就像Python中的split()一样。您可以使用map()迭代器适配器将每个部分转换为数字:

let mut s = String::new();
std::io::stdin().read_line(&mut s).expect("read_line error");

let mut parts = s.split_whitespace().map(|s| s.parse::<i32>());
match (parts.next(), parts.next()) {
    (Some(Ok(a)), Some(Ok(b))) => {
        // a and b are i32
    }
    // handle other problems: not enough numbers, numbers are invalid, etc
    _ => {}  // ignore invalid input
}

这看起来比Python版本更冗长,但这主要是因为在Python中所有错误都会被抛出作为异常,而在Rust中你必须明确地处理它们。如果你不关心它们,你可以抛弃match

let a = parts.next().unwrap().unwrap();
let b = parts.next().unwrap().unwrap();

另一种方法是为collect()使用方便的Result<Vec<_>, _>实现:

let items: Result<Vec<i32>, _> = parts.collect();

这样,如果输入字符串中的任何数字都无法解析,items将包含相应的Err值,但如果它们都被成功解析,那么items将包含{ {1}}带有解析数字向量的变体。使用这种方法,您也不需要在Ok调用中指定::<i32>(),因为它将自动推断(也不需要parse()):

mut

此外,没有单行函数可以从标准库中的标准输入读取字符串。这有点不幸但很少在实践中出现问题。有些库提供这样的功能;看其他答案,找一些例子。

答案 1 :(得分:4)

您可以使用提供宏read!的{​​{3}} crate来读取标准输入以生成元组:

#[macro_use] extern crate text_io;
let (a, b): (i32, i32);
scan!("{} {}", a, b);

您还可以逐个阅读值

#[macro_use] extern crate text_io;
let a: i32 = read!();
let b: i32 = read!();

答案 2 :(得分:2)

Rust代码总是比Python代码更冗长。但是每晚Rust还支持切片模式,如下所示。在我看来,代码看起来更具可读性。

#![feature(slice_patterns)]
fn main(){
    let a = "2 3";
    if let [Ok(aa), Ok(aaa)] = &a.split(" ")
                                 .map(|a| a.parse::<i32>())
                                 .collect::<Vec<_>>()[..]{
        println!("{:?} {:?}", aa, aaa);
    }
}