我在STDIN上写了一串数字(例如" 4 10 30 232312")我想读取它并转换为Rust中的int(或向量)数组,我找不到正确的方法,到目前为止我已经:
use std::io;
fn main() {
let mut reader = io::stdin();
let numbers = reader.read_line().unwrap();
}
提前谢谢
答案 0 :(得分:12)
针对Rust 1.x进行了更新
您可以这样做:
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()
的{{1}}迭代器,因此只需获得Option<io::Result<String>>
String
两次{/ 1}}。
然后我们用空格分割它并从额外的空格(2)中修剪得到的块,删除修剪后留下的空块(3),将字符串转换为unwrap()
s(4)并将结果收集到向量(5)。
我们还需要导入i32
特征(a)才能使用std::io::BufRead
方法。
如果您事先知道您的输入在数字之间不会包含多个空格,则可以省略步骤(3)并将lines()
调用从(2)移至(1):
trim()
<强>更新强>
然而, Rust已经提供了一种方法,将字符串拆分为一系列以空格分隔的单词,称为split_whitespace()
:
let numbers: Vec<i32> =
reader.lock()
.lines().next().unwrap().unwrap()
.trim().split(' ')
.map(|s| s.parse().unwrap())
.collect();
let numbers: Vec<i32> =
reader.read_line().unwrap().as_slice()
.split_whitespace()
.map(|s| s.parse().unwrap())
.collect()
实际上只是split_whitespace()
和split()
的组合,就像我原来的例子一样。它使用filter()
参数中的函数,但它检查不同类型的空格,而不仅仅是空格字符。您可以找到它的来源here。
答案 1 :(得分:12)
在Rust 1.5.x上,一个可行的解决方案是:
fn main() {
let mut numbers = String::new();
io::stdin().read_line(&mut numbers).ok().expect("read error");
let numbers: Vec<i32> = numbers
.split_whitespace()
.map(|s| s.parse().unwrap())
.collect();
for num in numbers {
println!("{}", num);
}
}
答案 2 :(得分:1)
更安全的版本。这个跳过失败的解析,因此失败的解包不会引起恐慌。
使用services.AddDbContext<AuthDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<AuthDbContext>()
.AddDefaultTokenProviders();
读取单行。
read_line
你甚至可以像这样阅读Vector of Vector。
let mut buf = String::new();
// use read_line for reading single line
std::io::stdin().read_to_string(&mut buf).expect("");
// this one skips failed parses so that failed unwrap doesn't panic
let v: Vec<i32> = buf.split_whitespace().filter_map(|w| w.parse().ok()).collect();
上面的内容适用于
等输入let stdin = io::stdin();
let locked = stdin.lock();
let vv: Vec<Vec<i32>> = locked.lines()
.filter_map(
|l| l.ok().map(
|s| s.split_whitespace()
.filter_map(|word| word.parse().ok())
.collect()))
.collect();
然后把它变成
2 424 -42 124
42 242 23 22 241
24 12 3 232 445
[[2, 424, -42, 124],
[42, 242, 23, 22, 241],
[24, 12, 3, 232, 445]]
接受一个返回filter_map
的闭包,并过滤掉所有Option<T>
。
None
将ok()
变为Result<R,E>
,以便在这种情况下可以过滤错误。