1

我正在按照这个参考来实现一个计算最小输入数的简单程序:

use std::io::prelude::*;
use std::io;

fn read_vec() -> Vec<i32> {
    let mut vec: Vec<i32> = Vec::<i32>::new();

    let stdin = io::stdin();
    println!("Enter a list of numbers, one per line. End with Ctrl-D (Linux) or Ctrl-Z (Windows).");
    
    for line in stdin.lock().lines() {
        let line = line.unwrap();
        match line.trim().parse::<i32>()  {
            Ok(num) => vec.push(num),
            Err(_) => println!("What did I say about numbers?"),
        }
    }

    vec
}

pub enum SomethingOrNothing<T> {
    Something(T),
    Nothing,
}

pub use self::SomethingOrNothing::*;

type NumberOrNothing = SomethingOrNothing<i32>;

pub trait Minimum: Copy {
    fn min(self, b: Self) -> Self;
}

pub fn vec_min<T: Minimum>(v: Vec<T>) -> SomethingOrNothing<T> {
    let mut min = Nothing;
    for e in v {
        min = match min {
            Something(t) => Something(e.min(t)),
            Nothing => Something(e),
        }
    }
    min
}

impl Minimum for i32 {
    fn min (self, b: Self) -> Self {
        if self < b {self} else {b}
    }
}

impl NumberOrNothing {
    pub fn print(self) {
        match self {
            Nothing => println!("The number is: <nothing>"),
            Something(n) => println!("{}", n),
        };
    }
}

fn main() {
    let vec = read_vec();
    let min = vec_min(vec);
    min.print();
}

构建运行程序:

Enter a list of numbers, one per line. End with Ctrl-D (Linux) or Ctrl-Z (Windows).
100
8
200
8D

我们可以看到D在最小数字之后有一个尾随的“”:8。但是,如果我将输出更改为:

Something(n) => println!("{}", n),

至:

Something(n) => println!("The number is: {}", n),

输出看起来很正常:

Enter a list of numbers, one per line. End with Ctrl-D (Linux) or Ctrl-Z (Windows).
100
8
200
The number is: 8

我猜这个问题与标准输出缓冲区有关,但不知道为什么。任何人都可以提供一些线索吗?

PS,我可以在macOS( zsh) 和OmniOS( bash) 上重现此问题,但无法在Linux( bash) 上重现。

4

1 回答 1

1

我能够使用 iTerm 在 macOS 上重新创建它(使用 zsh 和 bash 测试)。看起来问题与终端回显信号控制命令有关:

所以要停止这个,你需要关闭echoctl

查看正在发生的事情的最简单方法是Crtl-D在仍然与数字对齐时点击:

Enter a list of numbers, one per line. End with Ctrl-D (Linux) or Ctrl-Z (Windows).
1
2
3
4^D

在您的情况下发生的事情是:您在一个空行上并点击Ctrol-D,终端回^D显到该行,然后将光标移回该行的开头,然后您的程序输出覆盖^D. 因此,如果您输出一个数字,则将^被覆盖,但D仍会保留(如您的示例中所示)。当您输出更多字符时,^和 将D被覆盖。

D这是一个被覆盖的演示:

Enter a list of numbers, one per line. End with Ctrl-D (Linux) or Ctrl-Z (Windows).
100
200
300
100
于 2021-07-01T13:24:57.923 回答