Rust没有正确读取整数输入

Kav*_*sey 1 rust

我试图用一个简单的程序测试我的Rust技能,该程序从一行输入中读取多个整数.它编译正确,但不幸的是,当它收到输入时1 2 3,它会发生恐慌,说输入不是有效的整数.有人可以解释一下这个的原因,并解释我如何修复我的程序?

use std::io;

fn main() {
    let mut string = String::new();
    io::stdin().read_line(&mut string);

    let int_vec: Vec<u32> = string.split(" ")
        .map(|x| x.parse::<u32>().expect("Not an integer!"))
        .collect();

     for i in (0..int_vec.len()).rev() {
         print!("{} ", int_vec[i]);
     }
}
Run Code Online (Sandbox Code Playgroud)

Sim*_*ead 10

除了Dogberts的答案之外......看看你将来如何使用迭代器来调试这类问题可能会有所帮助.

Iterator特征公开了一个inspect可用于检查每个项目的功能.将代码转换为inspect在每个映射之前和之后使用都会导致:

let int_vec: Vec<u32> = string.split(" ")
.inspect(|x| println!("About to parse: {:?}", x))
.map(|x| {
    x.parse::<u32>()
        .expect("Not an integer!")
})
.inspect(|x| println!("Parsed {:?} successfully!", x))
.collect();
Run Code Online (Sandbox Code Playgroud)

输出:

1 2 3
About to parse: "1"
Parsed 1 successfully!
About to parse: "2"
Parsed 2 successfully!
About to parse: "3\n"

thread '<main>' panicked at 'Not an integer!...
Run Code Online (Sandbox Code Playgroud)

注意它到达数字3时尝试解析的内容.

当然,你可以string自己检查所有.inspect虽然涉及到迭代器,但是很方便.

  • TIL:有一个`inspect`功能!确实非常有用,可以在流中间窥视. (2认同)

Dog*_*ert 8

这是因为io::stdin().read_line(&mut String)还增加了尾部的换行符的字符串,这会导致分裂后的最后STR " ""123\n",这不是一个有效的整数.你可以使用str::trim()这个:

use std::io;

fn main() {
    let mut string = String::new();
    io::stdin().read_line(&mut string);

    let int_vec: Vec<u32> = string.trim()
        .split(" ")
        .map(|x| {
            x.parse::<u32>()
                .expect("Not an integer!")
        })
        .collect();

    for i in (0..int_vec.len()).rev() {
        print!("{} ", int_vec[i]);
    }
}
Run Code Online (Sandbox Code Playgroud)

通过此更改,该程序可以正常工作:

$ ./a
1 2 3
3 2 1
Run Code Online (Sandbox Code Playgroud)

此外,您可以简化for循环:

for i in int_vec.iter().rev() {
    print!("{} ", i);
}
Run Code Online (Sandbox Code Playgroud)


Luk*_*odt 5

你遇到了终止行结束的老问题.我们试试吧

println!("{:?}", string); 
Run Code Online (Sandbox Code Playgroud)

在代码的第三行.对于输入1 2 3,它将打印(在Windows上):

"1 2 3\r\n"
Run Code Online (Sandbox Code Playgroud)

所以在某些时候你试图解析"3\r\n"为整数,这显然是失败的.从字符串中删除尾部和前导空格的一种简单方法是使用trim().这有效:

let int_vec: Vec<_> = string.trim().split(" ")
    .map(|x| x.parse::<u32>().expect("Not an integer!"))
    .collect();
Run Code Online (Sandbox Code Playgroud)