c - 如何使用 read() 系统调用将用户输入编写到程序中?

标签 c system-calls buffering

我正在 Linux 环境中使用几个二进制文件,并且正在尝试编写用户输入的脚本。例如,对于第一个程序 prog1.c:

void get_input() {

    int i;
    char buffer[32];

    i = 0;

    while (i < 3) {
        memset(buffer, 0, 32);
        printf("Enter input: ");
        fgets(buffer, 31, stdin);
        printf("Your input: %s\n", buffer);
        i++;
    }
}

我可以运行 prog1 并直接从控制台输入输入,也可以编写输入脚本并将其通过管道传输到程序中。

直接从控制台输入内容:

# ./prog1
Enter input: Stuff1
Your input: Stuff1

Enter input: Stuff2
Your input: Stuff2

Enter input: Stuff3
Your input: Stuff3

#

脚本输入:

# perl -e 'print "Stuff1\n" . "Stuff2\n" . "Stuff3\n"' | ./prog1
Enter input: Your input: Stuff1

Enter input: Your input: Stuff2

Enter input: Your input: Stuff3

#

虽然输出的格式有点困惑,但程序仍然显示了预期的输出。

我的问题是第二个二进制文件 prog2.c:

void get_input() {

    int i;
    char buffer[32];

    i = 0;
    while (i < 3) {
        memset(buffer, 0, 32);
        printf("Enter input: ");
        read(0, buffer, 31);
        printf("Your input: %s\n", buffer);
        i++;
    }
}

当我可以直接从控制台输入输入时:

# ./prog2
Stuff1
Enter input: Your input: Stuff1

Stuff2
Enter input: Your input: Stuff2

Stuff3
Enter input: Your input: Stuff3

#

不仅在我输入后才出现输入提示,而且我什至无法编写输入脚本:

# perl -e 'print "Stuff1\n" . "Stuff2\n" . "Stuff3\n"' | ./prog2
Enter input: Your input: Stuff1
Stuff2
Stuff3

Enter input: Your input:
Enter input: Your input:
#

我对 fgets()read() 之间的差异进行了一些研究,并发现:

  1. fgets() 是一个 C 函数,而 read() 是一个系统调用。
  2. fgets() 读取输入,直到遇到换行符或 EOF,而换行符对 read() 系统调用没有相同的效果。
  3. read() 采用了 fgets() 没有的某种缓冲机制。

我认为第 2 点和第 3 点与当前问题最相关,但它们并没有暗示我如何解决我的问题。

我需要给这些程序的用户输入涉及不可打印的十六进制字节,这就是为什么直接从控制台输入此类输入是不够的。我也无法修改二进制文件的源代码,因此没有解决方法可以仅使用 fgets() 来收集输入。

我的问题是是否有任何方法可以将输入提供给 prog2,以便我获得与 prog1 相同的行为。

谢谢。

最佳答案

read(2)不缓冲但 fgets/printf/etc来自<stdio.h>这样做以获得更好的性能。

如果你想阅读行,请坚持使用 fgets 。但如果您想读取不可打印的数据 block (即二进制),请使用 fread 。无论如何,请检查返回值。

关于c - 如何使用 read() 系统调用将用户输入编写到程序中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43311391/

相关文章:

c - 用 C 将数字序列写入文件

c - 对文件 C 中的行进行排序

javascript - JavaScript的 `new Date().getTime()`在Windows中如何获取本地时间?

c - 如何给Linux系统调用传递参数?

python - 关闭前冲洗管道 (os.pipe)

c - Unix Sockets 的缓冲特性

c - 如何编写可重用的日志记录函数

c - gdk_screen_get_default() 和 get_width()/height() 段错误

linux - Linux 中多个系统调用的原因