【问题标题】:Reading from stdin从标准输入读取
【发布时间】:2013-03-30 19:10:05
【问题描述】:

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

【问题讨论】:

  • 你应该阅读read()手册
  • Read 会很好地做到这一点,但取决于你想要做什么,你可能会发现你需要做的不仅仅是调用 read - 你能发布你的代码,并准确解释哪一部分你有问题吗?
  • 我同意 Mats 的观点,您在此处寻找什么excatly?问题出在哪里? There are 也有很多不同的examples this on SO 怎么办,提问前有没有搜索一下?

标签: c unix stdin


【解决方案1】:

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

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

记住read() 不会添加'\0' 来终止以使其成为字符串(只提供原始缓冲区)。

一次读取 1 个字节:

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)

所以STDIN_FILENO 你可以使用 0。

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

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

注意评论/* Standard input. */

【讨论】:

  • 为什么在手册页中,它使用了“应该尝试”这个词。是否存在 read 无法准确读取第三个参数指定的字节数的情况? linux.die.net/man/3/read
【解决方案2】:

来自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()
   ....
}

【讨论】:

  • 你可以先使用int fileno(FILE *stream)
  • @Grijesh - 你可以更进一步,stdin 将是 0,所以你可以只需要read(0,... 不需要到处搜索stdin 的文件号在 *NIX 系统上
  • @Mike Yes I stdin = 0, stdout = 1, stderr = 2 和 good 对于所有操作系统都是一样的。
  • @MOHAMED 等等,不要删除你的答案。过一段时间我会添加一些细节。
  • @GrijeshChauhan 我不会这样做我根据你的评论更新了它