问题描述
我按照这个 reference 来实现一个计算最小输入数的简单程序:
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!("{}",
到:
Something(n) => println!("The number is: {}",
输出似乎正常:
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
({ {1}})。
解决方法
我能够使用 iTerm 在 macOS 上重新创建它(使用 zsh 和 bash 测试)。看起来问题与终端回显信号控制命令有关:
- https://linux.m2osw.com/remove-ctrl-C-from-being-printed-in-console
- https://unix.stackexchange.com/questions/558694/why-do-terminals-sometimes-echo-special-characters-like-c
因此,要停止此操作,您需要关闭 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