2017-04-09 73 views
-1

我正在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发现:

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

我认为要点2和3与手头的问题最相关,但他们没有向我提示如何解决我的问题。

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

我的问题是,如果有任何方法将输入馈送到prog2,以便我得到与prog1相同的行为。

谢谢。

+0

寻求调试帮助的问题(“为什么这个代码不工作?”)必须包含所需的行为,特定的问题或错误以及在问题本身中重现问题所需的最短代码。没有明确问题陈述的问题对其他读者无益。请参阅:如何创建最小,完整和可验证示例。 – Olaf

+0

函数:'fgets()'足够聪明地停止输入字节,同时还有一个'备用'字节可用于将NUL('\ 0')字节放在输入末尾。因此,缓冲区长度参数应该是缓冲区的实际长度 – user3629249

+0

问题已经完全改变。 –

回答

0

我找到了解决此问题的解决方法。我仍然无法按照我想要的方式与二进制文件进行交互 - 从控制台编写输入脚本 - 但我找到了一种以编程方式执行此操作的方法。

我使用Python库套件,作为一个包装到subprocess模块,但你可以简单地写自己:

p = subprocess.Popen(prog2, stdout=subprocess.PIPE, stdin=subprocess.PIPE) 

这将打开二进制作为一个过程,然后就可以使用Python脚本中的发送和接收函数与它进行交互。

我希望这可以帮助任何遇到类似问题的人。

3

read(2)不缓冲,但fgets/printf/etc<stdio.h>做更好的性能。

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

+0

调试时,我在gdb中输入脚本时发现以下内容;这是)读取之后寄存器的状态(致电: EAX:为0x15 ECX:0xbffff60c( “Stuff1 \ nStuff2 \ nStuff3 \ n”) 我可能已经猜到,从输出,但它不”帮我找到解决方法。 –

1

读取 '二进制' 文件时(可包含NUL字节,等等)使用 '读()' 或 '的fread()'

当读取一个文本文件时,使用 '与fgets()'

+0

我同意,但正如原始问题所述,我没有修改源的选项,所以我必须使用我的工作。 –

相关问题