为什么标准输入的 read() 在换行时停止?

问题描述 投票:0回答:1

如果如下代码

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

执行从终端读取,

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

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

c linux posix
1个回答
0
投票

标准输入在您的案例中被阻止。

read
阻塞直到至少有一个字节可用,然后可以返回任意大小的块。你不能对它会读取多少做出任何假设,它甚至可能总是返回一个字节。

在大多数情况下,它将读取当前可用的尽可能多的内容并返回。默认情况下,终端在所谓的“规范模式”下运行,并使输入逐行可用。您可以在 termios(3) 手册页中阅读更多相关信息。所以

read
在你按下 enter 之前甚至不能得到一个字节。然后该行可用,读取获取整行并返回而不等待更多数据。

如果您想禁用规范模式并在用户在终端中键入字节后立即接收字节,则在How to read terminal's input buffer immediately after keypress

中有一个相关的问题

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

在 EOF 条件下

read
返回 0,它在手册页中有记录。如果要读取整个文件,需要循环调用
read
,直到返回0。如果
read
返回-1,则表示出错。

如果你想逐行读取文件,你需要在你的应用程序中实现缓冲。继续在循环中调用

read
,直到缓冲区中有一个换行符。然后处理该行,保留剩余部分并重新开始阅读。或者,使用
stdio.h
功能,例如
fgets
为您实现缓冲。

© www.soinside.com 2019 - 2024. All rights reserved.