我在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相同的行为。
谢谢。
答案 0 :(得分:3)
read(2)
不会缓冲,但来自fgets/printf/etc
的{{1}}可以提高性能。
如果您想阅读行,请坚持使用<stdio.h>
。但是,如果要读取不可打印数据块(即二进制),请使用fgets
。无论如何,请检查返回值。
答案 1 :(得分:1)
在阅读“二进制文件”时文件(可以包含NUL字节等)使用&#39; read()&#39;或者&#39; fread()&#39;
阅读文字文件时,请使用&#39; fgets()&#39;
答案 2 :(得分:0)
我找到了解决此问题的方法。我仍然无法按照我想要的方式与二进制文件进行交互 - 从控制台编写我的输入脚本 - 但我找到了一种以编程方式执行此操作的方法。
我正在使用一个Python库套件作为subprocess
模块的包装器,但您可以自己编写:
p = subprocess.Popen(prog2, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
这将打开二进制文件作为一个进程,然后您可以使用Python脚本中的发送和接收函数与它进行交互。
我希望这可以帮助遇到类似问题的其他人。