我正在 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()
之间的差异进行了一些研究,并发现:
fgets()
是一个 C 函数,而read()
是一个系统调用。fgets()
读取输入,直到遇到换行符或 EOF,而换行符对read()
系统调用没有相同的效果。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/