【问题标题】:How does the read() function work? (What happens to the unread data in the buffer?)read() 函数是如何工作的? (缓冲区中的未读数据会怎样?)
【发布时间】:2021-12-12 04:07:02
【问题描述】:

我试图在 while 循环中使用 read() 作为条件从终端读取输入,但代码在循环结束之前不会被执行。

这是我的代码:

#include<unistd.h>
int main(void)
{
    char ch;
    while(read(STDIN_FILENO,&ch,1) == 1 && ch != 'q')
    {
        printf("success");
    }
    return 0;
}

它给了我输出:

t
fgr
vr

q
successsuccesssuccesssuccesssuccesssuccesssuccesssuccesssuccesssuccess

即使我尝试正常读取数据,缓冲区中的未读数据也会这样结束。

代码:

#include<unistd.h>
int main(void)
{
    char ch;
    read(STDIN_FILENO,&ch,1);
    return 0;
}

终端输出

user1@lap:~/Desktop$ ./program2e3
ted
pradeep@LLP:~/Desktop$ ed

为什么未读的数据会变成下一条命令?

【问题讨论】:

  • 那是因为stdin不是普通的文件流而是终端输入流。如果你这样说,行为更像你所期望的:echo "test" | ./program2e3
  • 您的问题应该只集中在一个问题上(更加集中)。有关您问题的第一部分,请参阅Why does printf not flush after the call unless a newline is in the format string?。对于第二部分:您没有读取整个输入,因此 shell 会读取剩余的字符并显示在下一个命令行中。
  • 感谢您的回复,以后我会更加专注。您能否向我推荐任何与终端如何工作相关的资源,例如它如何处理输入和输出缓冲区.. ..
  • 终端的低级控制是通过termios函数。如果标准输入是终端,isatty(STDIN_FILENO) 将返回 1。要获得更轻松、便携、更高级别(完整终端)的访问权限,请使用ncurses。 (您可以在 vi、emacs、nano 等终端中运行的所有编辑器都使用 ncurses。)

标签: c linux terminal unistd.h


【解决方案1】:

由于数据仍在内核的 IO 缓冲区中,而不是您进程中的 STDIO 缓冲区中,因此未读取的数据将被下一个尝试读取它的进程(即 shell 进程)读取。这是因为打开的句柄是从 shell 进程传递到您的进程的。如果您自己打开 tty 设备,就不会发生这种情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 2011-03-01
    • 2015-04-24
    • 1970-01-01
    • 2011-10-18
    相关资源
    最近更新 更多