用c中的read()函数读取STDIN:一个澄清



我正在尝试写一种最简单、最低级别、最基本的方式来读取STDIN,并在达到一定大小(比如说16个字符?(时对读取的内容进行处理。考虑一下这个片段:

#include <unistd.h>
#include <stdio.h>
#define BUFF 16
int main()
{
char buf[BUFF];
int just_read = -1;
while(just_read != 0)
{
printf("entering the loopnjust_read: %dn", just_read);
just_read = read(0, buf, BUFF);
}
}

我告诉read((函数尝试读取BUFF字符(在本例中为16个(,但如果我在stdin中引入一个带有Enter的新行,我可以从调试printf行中看到,我正在启动另一个循环,而我天真地希望在读取16个字符之前一直呆在read(((中。Enter发送的信号是什么?用每个BUFF字符读取的数据做某事(比如说在STDOUT上写(最精简的方法是什么?

BUFF 5的输出ex:

stdin:
12<enter>
45678<ctrl+d>
stdout:
12
45

您需要跟踪buf中添加数据的最后一个位置。您需要给buf的下一个字节一个指针来添加数据。

通常是这样的:

ssize_t read_all(int fd, char *buffer, size_t to_read)
{
// The position to read into
char *current_pos = buffer;
while (to_read > 0)
{
ssize_t nread = read(fd, current_pos, to_read);
if (nread < 0)
{
// Error
return -1;
}
else if (nread == 0)
{
// End of the file or input
break;
}
// Next position to read into
current_pos += nread;
// We have read some, read less next time
to_read -= nread;
}
// At this point we either have read all
// or we have reached the end of the file/input
// Return how much we actually did read
return current_pos - buffer;
}

read_all函数将尝试将所有内容读取到所提供的缓冲区中。它将在出现错误时返回-1,或者返回实际读取的大小。如果有文件结尾,则返回的值将小于请求的值(如果EOF是第一件发生的事情,则可能是0(。

你可以这样使用它:

char buf[BUFF];
ssize_t nread = read_all(STDIN_FILENO, buf, sizeof buf);
if (nread == -1)
{
perror("read_all");
}
else if (nread < sizeof buf)
{
printf("Short read of %zd bytes: %*sn", nread, nread, buf);
}
else
{
printf("Read everything (%zd bytes): %*sn", nread, nread, buf);
}

最新更新