【发布时间】:2022-01-18 10:19:02
【问题描述】:
我在玩下面两个代码sn-ps
// Snippet1 in C
#include <stdio.h>
int main(){
FILE * fp = fopen("/dev/tty", "r");
int c = getc(fp);
printf("%d", c);
}
// Snippet2 in Rust
use std::io::Read;
use std::fs;
fn main() {
let mut f: fs::File = fs::File::open("/dev/tty").unwrap();
let mut buf: [u8;1] = [0];
f.read_exact(&mut buf).unwrap();
print!("byte: {}", buf[0]);
}
上面的代码要做的是从用户键盘读取一个字节,然后将它打印到标准输出。 令人困惑的是两个 sn-ps 有不同的行为:
➜ playground gcc main.c -o main
➜ playground ./main
a # input a and press Enter
97%
➜ playground cargo run -q
a # input a and press Enter
byte: 97% ➜ playground
➜ playground
不好意思上面代码的格式,不知道怎么把提示放在换行的开头:(
请注意,Rust代码执行后有两个 shell提示➜ playground?
我猜Enter 被发送到输入缓冲区,就好像我在执行后按下它一样。
如果我知道缓冲区中实际发生了什么,我会找出这种区别的原因,所以我想知道那里发生了什么?
顺便说一句,我的环境:
➜ playground rustc --version
rustc 1.57.0 (f1edd0429 2021-11-29)
➜ playground gcc --version
gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
如果我的问题不被允许,请随时要求我删除它:) 在此先感谢:)
【问题讨论】:
-
好吧,
read_exact显然没有读取换行符,因为它不适合缓冲区。我猜getc只是默默吞下它? -
换行符实际上是写入 /dev/tty 的。因此,如果再次调用 getc,它应该读取换行符。
-
@Cerberus 感谢您的评论!有两种读取流,一种直接从键盘读取(char a),另一种从标准输入(Enter keystroke)读取。而在我看来,
getc属于前者,因为它只从它的参数(文件 /dev/tty)中读取,也许它是吞下输入的其他东西? -
@kiner_shah,谢谢您的评论!你能进一步解释为什么
Newline is written to /dev/tty actually吗?我的想法是当我输入“a”时,getc完成了它的工作,并且换行符被写入输入缓冲区。 -
@SteveLau,我运行了以下代码,您可以看到 10 是输出(换行符的 ASCII),只要您打印输入。 onlinegdb.com/AUkca3lGy
标签: c linux rust buffer input-buffer