使用无缓冲 IO 例程询问和读取用户输入

asking and reading in user input using unbuffered IO routines

我们刚刚开始讨论 C 中的低级函数,对于此作业的一部分,我们必须征求用户的意见。通常我会使用 printf() 和 scanf() 但是对于这个作业我们只允许使用 read()、write()、open()、close() 和 lseek()。

我的问题是打印到屏幕后如何从键盘读取输入? 我知道我必须使用 read,文件描述符将是 STDIN_FILENO,但是我如何确定大小计数?另外我将如何跟踪用户输入的内容?我是否必须为此创建一个 char 数组?

此外,如果任何人都可以参考一些好的读物 material 或使用低级函数进行编程的教程,将会有很大帮助。

逐个读取一个字符对性能不利。系统调用有点昂贵。通常你需要某种缓冲区(malloced,静态内存,在堆栈上)。 尺寸(一旦超过一定尺寸)并不那么重要。

如果您的 fd 0 是处于熟化模式的终端,您将在每次调用 read 时得到一行(这通常无法填满整个缓冲区)。重要的是要认识到,N 字节的读取请求不需要 return N 字节,小于 N 字节的 return 不需要表示 IO 错误。如果它是基于磁盘的文件,那么您对缓冲区大小的读取请求往往会被完全填满。

Richard Stevens 的 Advanced Programming in the Unix Env​​ironment 是一本关于此的好书。 然后当然是系统调用的手册页。

继续我之前的评论,使用 readwrite 读取和写入 stdin 与使用更高级别的函数(如 fgetsprintf。主要区别在于您不能依赖可变参数 printf 提供的格式字符串,而对于 read,您负责使用 return 来了解实际读取了多少字符.

下面是一个简短的示例,展示了使用 readstdin 读取输入然后使用 write 写回该信息的基础知识(注意: 你应该添加额外的检查,比如检查读取的字符数是否小于缓冲区的大小,以了解是否还有更多字符需要读取,等等......)你总是可以把大部分的提示和read 到一个函数中以简化重复使用。

使用 write,请记住,您将内容写入 stdout 的顺序是 格式字符串。因此,只需对 write 进行逻辑调用即可完成所需的格式设置。虽然您可以自由使用 STDIN_FILENO 定义,但您也可以简单地使用 0 - stdin1 - stdout2 - stderr:

#include <unistd.h>

#define MAXC 256

int main (void) {

    char buf[MAXC] = {0};
    ssize_t nchr = 0;

    /* write the prompt to stdout requesting input */
    write (1, "\n enter text  : ", sizeof ("\n enter text  : "));

    /* read up to MAXC characters from stdin */
    if ((nchr = read (0, buf, MAXC)) == -1) {
        write (2, "error: read failure.\n", sizeof ("error: read failure.\n"));
        return 1;
    }

    /* test if additional characters remain unread in stdin */
    if (nchr == MAXC && buf[nchr - 1] != '\n')
        write (2, "warning: additional chars remain unread.\n",
            sizeof ("warning: additional chars remain unread.\n"));

    /* write the contents of buf to stdout */
    write (1, "\n text entered: ", sizeof ("\n text entered: "));
    write (1, buf, nchr-1);
    write (1, "\n\n", sizeof ("\n\n"));

    return 0;
}

编译

gcc -Wall -Wextra -o bin/read_write_stdin read_write_stdin.c

输出

$ ./bin/read_write_stdin

 enter text  : The quick brown fox jumps over the lazy dog!

 text entered: The quick brown fox jumps over the lazy dog!