我在STDIN上写了一个数字字符串(例如4 10 30 232312
),我想读取该数字并将其转换为整数数组(或向量),但是我找不到正确的方法。到目前为止,我有:
use std::io;
fn main() {
let mut reader = io::stdin();
let numbers = reader.read_line().unwrap();
}
您可以执行以下操作:
use std::io::{self, BufRead}; // (a)
fn main() {
let reader = io::stdin();
let numbers: Vec<i32> =
reader.lock() // (0)
.lines().next().unwrap().unwrap() // (1)
.split(' ').map(|s| s.trim()) // (2)
.filter(|s| !s.is_empty()) // (3)
.map(|s| s.parse().unwrap()) // (4)
.collect(); // (5)
println!("{:?}", numbers);
}
首先,我们锁住了stdin,这使您可以将stdin用作缓冲读取器。默认情况下,Rust中的stdin是无缓冲的;您需要调用lock()
方法来获取其缓冲版本,但是该缓冲版本是程序中所有线程的唯一缓冲版本,因此应该同步对其的访问。]
接下来,我们阅读下一行(1);我正在使用lines()
迭代器,该迭代器的next()
方法返回Option<io::Result<String>>
,因此,仅获取String
,您需要两次unwrap()
。
然后我们用空格将其分割,并从多余的空白中修剪生成的块(2),删除修剪后剩下的空块(3),将字符串转换为i32
s(4),然后将结果收集为矢量(5) )。
我们还需要导入std::io::BufRead
特征(a)才能使用lines()
方法。
如果事先知道输入的数字之间不能包含多个空格,则可以省略步骤(3),并将trim()
调用从(2)移至(1):
let numbers: Vec<i32> = reader.lock() .lines().next().unwrap().unwrap() .trim().split(' ') .map(|s| s.parse().unwrap()) .collect();
Rust还提供了一种将字符串拆分为一系列用空格分隔的单词的方法,称为
split_whitespace()
:
split_whitespace()
let numbers: Vec<i32> = reader.read_line().unwrap().as_slice() .split_whitespace() .map(|s| s.parse().unwrap()) .collect()
实际上只是split_whitespace()
和split()
的组合,就像在我的原始示例中一样。它使用filter()
函数参数。
在Rust 1.5.x上,有效的解决方案是:
更安全的版本。这将跳过失败的分析,以便失败的展开不会引起恐慌。使用checks for different kinds of whitespace, not only space characters读取单行。