如何使用read()系统调用将用户输入编写到程序中?
我正在Linux环境中使用一对二进制文件,并且正在尝试编写我的用户输入。例如,与第一程序prog1.c的:如何使用read()系统调用将用户输入编写到程序中?
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:
当我可以从控制台直接进入我的输入:
# ./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:
#
我做了一些关于d fgets()
和read()
之间ifferences发现:
-
fgets()
是一个C函数,而read()
是一个系统调用。 -
fgets()
读取输入,直到遇到换行符或EOF,而换行符对系统调用没有相同的效果。 -
read()
采用某种缓冲机制fgets()
没有。
我认为要点2和3与手头的问题最相关,但他们没有向我提示如何解决我的问题。
我需要给这些程序的用户输入涉及不可打印的十六进制字节,这就是为什么从控制台直接输入这样的输入是不够的。我也无法将源代码修改为二进制文件,所以没有解决方法只使用fgets()
来收集输入。
我的问题是,如果有任何方法将输入馈送到prog2,以便我得到与prog1相同的行为。
谢谢。
我找到了解决此问题的解决方法。我仍然无法按照我想要的方式与二进制文件进行交互 - 从控制台编写输入脚本 - 但我找到了一种以编程方式执行此操作的方法。
我使用Python库套件,作为一个包装到subprocess
模块,但你可以简单地写自己:
p = subprocess.Popen(prog2, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
这将打开二进制作为一个过程,然后就可以使用Python脚本中的发送和接收函数与它进行交互。
我希望这可以帮助任何遇到类似问题的人。
read(2)
不缓冲,但fgets/printf/etc
从<stdio.h>
做更好的性能。
如果你想读线,坚持fgets
。但是,如果您想读取不可打印数据块(即二进制),请使用fread
。无论如何,请检查返回值。
调试时,我在gdb中输入脚本时发现以下内容;这是)读取之后寄存器的状态(致电: EAX:为0x15 ECX:0xbffff60c( “Stuff1 \ nStuff2 \ nStuff3 \ n”) 我可能已经猜到,从输出,但它不”帮我找到解决方法。 –
读取 '二进制' 文件时(可包含NUL字节,等等)使用 '读()' 或 '的fread()'
当读取一个文本文件时,使用 '与fgets()'
我同意,但正如原始问题所述,我没有修改源的选项,所以我必须使用我的工作。 –
寻求调试帮助的问题(“为什么这个代码不工作?”)必须包含所需的行为,特定的问题或错误以及在问题本身中重现问题所需的最短代码。没有明确问题陈述的问题对其他读者无益。请参阅:如何创建最小,完整和可验证示例。 – Olaf
函数:'fgets()'足够聪明地停止输入字节,同时还有一个'备用'字节可用于将NUL('\ 0')字节放在输入末尾。因此,缓冲区长度参数应该是缓冲区的实际长度 – user3629249
问题已经完全改变。 –