【问题标题】:Weird behaviour when using read_line in a loop在循环中使用 read_line 时的奇怪行为
【发布时间】:2018-11-21 05:36:07
【问题描述】:

我在 Rust 中的第一个程序应该以字符形式(C 或 F)从用户那里获取输入:

use std::io;

fn main() {
    let mut srcunit = String::new();

    let mut switch = true;
    while switch {
        println!("source unit? F or C?");
        io::stdin().read_line(&mut srcunit).expect(
            "failed to read src unit",
        );

        if srcunit.trim() == "F" || srcunit.trim() == "C" {
            println!("doing things right with {}", srcunit);
            switch = false;
        } else {
            println!("either F or C, not {}", srcunit);
        }
    }

    println!("you pressed {}", srcunit);
}

当我启动程序并按 F 或 C 时,它工作正常,所以我在这里跳过。当我按下另一个字符时,奇怪的部分就出现了。我希望我的程序会再次询问 F 或 C,直到我按下其中一个字符。当我这样做时,它应该离开 while 循环并告诉我我按下了什么。

source unit? F or C?
G
either F or C, not G //so far so good

source unit? F or C?
F
either F or C, not G //why is F not assigned to the srcunit variable? It's supposed to leave the loop now.
F                    //why does it print this line? I didn't press a key or have a println function/macro that does this

source unit? F or C?
V
either F or C, not G //it's still G, wtf
F                    //again, why are those two lines printed? Where does it store, that I pressed F previously?
V

【问题讨论】:

    标签: rust


    【解决方案1】:

    来自documentation for read_line

    读取所有字节,直到到达换行符(0xA 字节),并将它们追加到提供的缓冲区。

    (强调我的。)您需要在读取下一行之前清除字符串,例如通过在字符串上调用clear() 方法,否则答案会累积在变量中。

    或者,您可以在循环中定义变量(但这效率稍低,因为这样String 将无法将已分配的存储空间重用于下一个答案,它必须被释放并再次重新分配)。

    另见this question,最近被问到。看起来这是一个常见的陷阱。

    【讨论】:

    • 换句话说,这些额外的行被打印出来,因为它们是srcunit 的一部分。 read_line 不断将新数据添加到它的末尾。
    • that example 中的关键示例(希望我得到了正确的链接)是变量是在循环中声明的,因此每次迭代都会自动重新创建它。
    猜你喜欢
    • 1970-01-01
    • 2013-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-31
    • 2019-02-11
    相关资源
    最近更新 更多