跳转到内容

Rust 初学者/基础数学测试程序/字符串到数字

来自维基教科书,开放的书籍,开放的世界

将字符串转换为数字

[编辑 | 编辑源代码]

现在我们已经从标准输入中读取了一个字符串。但我们想要将其转换为数字。为此,我们在 i32 内部使用以下函数

fn from_str_radix(src: &str, radix: u32) -> Result<i32, ParseIntError>

src 是我们要转换为数字的字符串。radix 是我们要转换到的数字的基数。我们只想要使用 10 进制,因为这是人们输入的方式。此外,该函数返回一个 Result,表明该函数可能会失败。我们可以在结果上使用 .unwrap(),但这意味着如果用户输入了任何无法转换为数字的内容,程序就会崩溃。相反,我们希望正确处理错误,如果用户输入无法转换为数字,我们应该要求用户重新输入。以下是示例代码

fn wait_for_input() -> i32 {
    let mut buffer = String::new();
    io::stdin().read_line(&mut buffer).unwrap();

    let mut result = i32::from_str_radix(&buffer, 10);

    while let Err(_) = result {
        println!("Invalid number, please re-enter:");
        buffer.clear();
        io::stdin().read_line(&mut buffer).unwrap();
        result = i32::from_str_radix(&buffer, 10);
    }

    let num = result.unwrap();

    num
}

请注意,我们在结果为错误时循环,因此最后面的 unwrap 始终是安全的。此外,我们必须在每次运行之间清除缓冲区。现在让我们测试一下,看看它是如何工作的!

What is 35 - 23?
5
Invalid number, please re-enter:
12
Invalid number, please re-enter:
6
Invalid number, please re-enter:

糟糕。请注意,我们在循环中使用 Ctrl-C 来退出程序。但问题是什么?为什么它无法正确解析字符串为数字?让我们添加一个调试 println!() 语句来查看 buffer 的值在解析之前是什么

println!("buffer: {:?}", buffer);

然后当我们运行它时,它会打印出

What is 35 - 23?
10
buffer: "10\r\n"
Invalid number, please re-enter:

字符串末尾的那些字符是什么?实际上,由于我们必须按 Enter 提交数字,这会向标准输入添加一个换行符,该换行符包含在缓冲区中。另一个令人讨厌的事情是换行符取决于你的操作系统,Windows 通常使用 “\r\n”,而其他操作系统使用 “\n”。我们想要处理这两种情况,因此我们将添加一行代码来用空字符串替换所有这些字符,因此我们的函数变为

fn wait_for_input() -> i32 {
    let mut buffer = String::new();
    io::stdin().read_line(&mut buffer).unwrap();
    buffer = buffer.replace("\r", "").replace("\n", "");

    let mut result = i32::from_str_radix(&buffer, 10);

    while let Err(_) = result {
        println!("Invalid number, please re-enter:");
        buffer.clear();
        io::stdin().read_line(&mut buffer).unwrap();
        buffer = buffer.replace("\r", "").replace("\n", "");
        result = i32::from_str_radix(&buffer, 10);
    }

    let num = result.unwrap();

    num
}

现在我们的函数可以正常工作了,当我们运行它时,我们会得到这些结果

What is 35 - 23?
test
Invalid number, please re-enter:
1s3r
Invalid number, please re-enter:
10

并且程序按预期退出!

下一步:检查用户输入的数字是否与预期数字匹配

华夏公益教科书