簡體   English   中英

從 /dev/tty 讀取時,輸入和鍵盤緩沖區中發生了什么?

[英]When reading from /dev/tty, what is happening in input and keyboard buffer?

我正在玩以下兩個代碼片段

// 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.

如果我的問題不被允許,請隨時要求我刪除它:) 提前致謝:)

請注意,在 C 中, FILE*和相應的函數被緩沖,因此 C 程序讀取鍵和換行符並將它們放入緩沖區,而您的 ZF5E265D607CB720058FC166E0008 代碼不使用緩沖代碼。 As a consequence the newline character is still in the kernel buffer for the TTY when your Rust program finishes and so the newline is seen by your shell, whereas the newline has been removed from the kernel buffer by your C program.

您應該使用此無緩沖 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]);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM