从标准输入读取

51

在Unix中,使用read()系统调用读取用户输入的可能方式有哪些?我们如何使用read()逐字节从标准输入读取数据?


2
请阅读read()手册。 - Grijesh Chauhan
1
读取操作可以很好地完成这个任务,但是根据你想要做什么,你可能会发现你需要做的不仅仅是调用read函数 - 你能否发布你的代码,并解释一下你遇到的具体问题? - Mats Petersson
我同意Mats的看法,你在这里到底要找什么?问题出在哪里? 这里有 很多不同的 示例 关于如何在SO上实现这个功能,你在提问之前有做过任何搜索吗? - Mike
2个回答

56

你可以像这样读取10个字节:

char buffer[10];
read(STDIN_FILENO, buffer, 10);

请记住,read()函数不会添加'\0'作为字符串终止符(只会提供原始缓冲区)。

要逐个字节读取:

char ch;
while(read(STDIN_FILENO, &ch, 1) > 0)
{
 //do stuff
}

不要忘记要 #include <unistd.h>STDIN_FILENO 在这个文件中被定义为宏。

有三个标准的 POSIX 文件描述符,对应着三个标准流,每个进程都应该期望拥有它们:

Integer value   Name
       0        Standard input (stdin)
       1        Standard output (stdout)
       2        Standard error (stderr)

因此,您可以使用0而不是STDIN_FILENO

编辑:
在Linux系统中,您可以使用以下命令找到它:

$ sudo grep 'STDIN_FILENO' /usr/include/* -R | grep 'define'
/usr/include/unistd.h:#define   STDIN_FILENO    0   /* Standard input.  */

注意注释 /*标准输入。*/


为什么在 man 手册中使用“shall attempt”这个词?是否存在一种情况,read 不会读取第三个参数指定的确切字节数?https://linux.die.net/man/3/read - weefwefwqg3
1
@weefwefwqg3 如果read()被信号中断,或者请求的字节数大于可用字节数等情况下,它将读取比请求的字节数更少的字节。 - camerondm9

17

来自man read

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);

输入参数:

  • int fd 文件描述符是整数而不是文件指针。标准输入(stdin)的文件描述符为 0

  • void *buf 指向存储read函数读取的字符的缓冲区的指针。

  • size_t count 最大要读取的字符数。

因此,您可以使用以下代码逐个字符读取:

char buf[1];

while(read(0, buf, sizeof(buf))>0) {
   // read() here read from stdin charachter by character
   // the buf[0] contains the character got by read()
   ....
}

2
你可以先使用 int fileno(FILE *stream) - Grijesh Chauhan
@Grijesh - 你可以更进一步,stdin 就是 0,所以你只需要 read(0,... 不需要在 *NIX 系统中搜索 stdin 的文件号。 - Mike
@Mike 是的,我将 stdin = 0stdout = 1stderr = 2,而且好消息是它在所有操作系统上都是一样的。 - Grijesh Chauhan
@MOHAMED 等等,不要删除你的回答。稍后我会添加一些细节。 - Grijesh Chauhan
@MOHAMED 请继续完善你的回答:添加两个要点(1)你可以使用char c; read(0, &c, 1)来进行读取,(2)read()函数不会像fgets()一样在输入缓冲区中加上\0。因此,如果有人想将缓冲区用作字符串,他必须显式地添加null,例如:no_byte = read(0, buffer, sizeof(buffer)-1); buffer[no_bytes] = '\0'; 这是新手容易犯错的地方,就像在这个问题中第二个错误一样...请继续,这就是我想要补充的内容。 - Grijesh Chauhan
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接