为什么我的 println!() 输出有尾随 "D"?
Why is there a trailing "D" of my println!() output?
我正在按照这个 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
我们可以看到在最小数字8
之后有一个尾随的“D
”。但是,如果我将输出更改为:
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
我猜这个问题与标准输出缓冲区有关,但无法弄清楚原因。谁能给点线索?
P.S.,我可以在 macOS
(zsh
) 和 OmniOS
(bash
) 上重现此问题,但无法在Linux
(bash
).
我能够使用 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
我正在按照这个 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
我们可以看到在最小数字8
之后有一个尾随的“D
”。但是,如果我将输出更改为:
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
我猜这个问题与标准输出缓冲区有关,但无法弄清楚原因。谁能给点线索?
P.S.,我可以在 macOS
(zsh
) 和 OmniOS
(bash
) 上重现此问题,但无法在Linux
(bash
).
我能够使用 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