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

Jay*_*man 5 input rust

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

a, b = map(int, input().split()) #  "2 3"  =>  a=2 and b=3
Run Code Online (Sandbox Code Playgroud)

从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");
Run Code Online (Sandbox Code Playgroud)

Vla*_*eev 8

&str有一个split_whitespace()方法,它返回一个迭代器,产生目标字符串的一部分,由任意数量的空格分隔,就像split()在Python中一样.您可以使用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
}
Run Code Online (Sandbox Code Playgroud)

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

let a = parts.next().unwrap().unwrap();
let b = parts.next().unwrap().unwrap();
Run Code Online (Sandbox Code Playgroud)

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

let items: Result<Vec<i32>, _> = parts.collect();
Run Code Online (Sandbox Code Playgroud)

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

let parts = s.split_whitespace().map(|s| s.parse());
Run Code Online (Sandbox Code Playgroud)

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


oli*_*obk 6

您可以使用text_io提供宏的包read!来从标准输入读取以生成元组:

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

也可以一一读取数值

#[macro_use] extern crate text_io;
let a: i32 = read!();
let b: i32 = read!();
Run Code Online (Sandbox Code Playgroud)