我正在玩以下兩個代碼片段
// 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]);
}
上面的代碼要做的是從用戶鍵盤讀取一個位元組,然后將其列印到標準輸出。令人困惑的是兩個片段有不同的行為:
? 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.
如果我的問題不被允許,請隨時要求我洗掉它:) 提前致謝:)
uj5u.com熱心網友回復:
請注意,在 C 中,FILE*相應的函式是緩沖的,因此 C 程式讀取鍵和換行符并將它們放入緩沖區中,而您的 Rust 代碼不使用緩沖。因此,當您的 Rust 程式完成時,換行符仍在 TTY 的內核緩沖區中,因此您的 shell 可以看到換行符,而換行符已被您的 C 程式從內核緩沖區中洗掉。
使用這個無緩沖的 C 代碼,你應該得到與你的 Rust 程式相同的行為:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main() {
int fd = open ("/dev/tty", O_RDONLY);
char c;
read (fd, &c, 1);
printf("%d", c);
}
或與您的 C 程式具有此緩沖 Rust 代碼的相同行為:
use std::io::{ BufReader, Read };
use std::fs;
fn main() {
let mut f = BufReader::new (fs::File::open("/dev/tty").unwrap());
let mut buf: [u8;1] = [0];
f.read_exact(&mut buf).unwrap();
print!("byte: {}", buf[0]);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/414774.html
標籤:
上一篇:套接字系結回傳相同的臨時埠
