如果以下代码

ssize_t len = read(0, buf, BUF_SIZE);
perror("read()");
printf ("%i '%s'\n", (int) len, buf);

执行从终端读取时,read()终止对换行符的输入(按Enter键),不显示任何错误,即导致逐行输入.但是,当我使用shell 将其重定向到来自文件的输入时,它会忽略换行符,并继续读取整个缓冲区或直到EOF.

根据文件,后一种行为更符合人们的预期.那么,为什么终端输入是在换行符上终止的?这是否意味着该输入在默认情况下是非阻塞的?判断是否达到EOF(Ctrl-D)或某些其他条件导致返回不完整的输入,正确的方法是什么?

推荐答案

在您的情况下,标准输入是阻塞的.read个块,直到至少有一个字节可用,然后可以返回任意大小的块.您不能对它将读取多少做出任何假设,它甚至可能总是返回一个字节.

在大多数情况下,它将读取当前可用的内容并返回.默认情况下,终端在所谓的"规范模式"下运行,并使输入逐行可用.您可以在Termios(3)手册页上阅读更多关于它的信息.因此,在您按Enter键之前,read连一个字节都不能得到.然后该行变为可用,READ获得整个行并返回,而无需等待更多数据.

If you want to disable canonical mode and receive bytes as soon as user types them in the terminal, there is a related question about it at How to read terminal's input buffer immediately after keypress

判断是否达到EOF(Ctrl-D)或某些其他条件导致返回不完整的输入,正确的方法是什么?

在EOF条件read返回0时,它记录在手册页中.如果您想读取整个文件,则需要在循环中调用read,直到它返回0.如果read返回-1,则表示错误.

如果要逐行读取文件,则需要在应用程序中实现缓冲.继续循环调用read,直到缓冲区中有换行符.然后处理这一行,保留剩余的部分,然后重新开始阅读.或者,使用stdio.h个函数,如fgets,它们为您实现缓冲.

C++相关问答推荐

了解返回函数指针的函数定义

如何从TPS特定的TGPT_PUBLIC数据 struct 中以OpenSSL的EVP_PKEY

为什么listen()(在调用accept()之前)足以让应用程序完成3次握手?

为什么在4.9.37版的内核中,kfio还需要smp_wmb呢?

以前版本的tty_ldisc_ops.ioctl()是否也需要文件参数?

为什么可以在typedef之前使用typedef d struct 体?

C是否用0填充多维数组的其余部分?

在C语言中,在数学运算过程中,为什么浮点数在变量中的行为不同

强制转换变量以在 struct 中蚕食

cairo 剪辑区域是否存在多个矩形?

S在本文中的价值观到底出了什么问题?

处理EPOLL_WAIT中的接收数据和连接关闭信号

在C++中允许使用字符作为宏参数

挥发性语义的形式化理解

变量值不正确的问题

从文件到链表读取日期

const struct 成员的 typedef 中的灵活数组大小

使用fread()函数读取txt文件

创建 makefile 来编译位于不同目录中的多个源文件

为什么需要struct in_addr