2015-09-01 53 views
3

我有一个非常简单的程序:当我使用'|'时会发生什么?或“<”,C++

void main() 
{ 
    fgets(buf,133,stdin); 
    printf(buf); 
    system("/bin/dash"); 
} 

当我启动程序,这一切工作正常,我可以输入任何我想要的,然后我有一个壳。但是,如果我为了自动补BUF(不使用键盘打字点儿)做

$ echo 'blabla' | ./test 

,外壳被执行,但是,/ bin中/ LS工作正常的情况下。 (显然的显示命令的工作精细)

如果删除了与fgets线,并且我执行相同的命令,它的工作原理,但需要的“布拉布拉”作为/斌/破折号的参数。然而,添加一个nul字符或返回'\ xd'来模拟我的键盘在fgets中的返回不起作用

我想了解当我使用'|'时会发生什么,符号在我的C++程序中。我认为这是在没有任何人为干预的情况下自动填充scanfs和fgets的解决方案,我是做错了还是有其他解决方案?

谢谢。

的Debian,C++ G ++

+2

在标准C++主总是返回'int' – NathanOliver

+1

HTTP://meta.stackexchan ge.com/questions/66377/what-is-the-xy-problem? –

+0

['void main()'](http://stackoverflow.com/q/204476/995714)是错误的 –

回答

2

如果我理解正确的话,你想既您fgets和你的shell提供输入,而是发现,当外壳没有收到任何输入你管。

这是因为会的libc缓冲输入数据以便fgets

代替读出7个字节在blabla\n,其余传递到外壳,它读取可达4096个字节(依赖于系统),并使用剩余的4089个字节用于在stdin未来fgets/f*呼叫。这些数据将被内部存储在您的程序中,并且不会被其他从底层流中读取的进程使用,如被调用的shell。

当您交互式运行并在键盘上键入时,只有7个字节 在您按回车时可用,所以缓冲区只填充7个字节。您键入的其余数据因此可用于shell。你可以有模拟同样的效果在你的错误的程序与输入战略地位延迟:

{ echo "for fgets"; sleep 1; echo "ls"; } | ./foo 

您可以通过设置缓冲区大小为1个字节规避这个问题,让fgets从不读取超过必要的:

#include <stdio.h> 

char input_buffer[1]; 

void main(int argc, char** argv) 
{ 
    char buf[133]; 
    setvbuf(stdin, input_buffer, _IOFBF, 1); 
    fgets(buf,133,stdin); 
    printf(buf); 
    system("/bin/dash"); 
} 

现在你可以用一个管和没有延迟运行它:

$ echo -e "for fgets\nls" 
for fgets 
ls 
$ gcc foo.c -o foo 
$ echo -e "for fgets\nls" | ./foo 
for fgets 
Desktop Downloads foo.c Pictures Steam  Videos 
Documents foo  Music Public Templates win 
+0

非常感谢!事情是,我想自动完成不是由我写的程序,所以我不能使用setvbuf,但是谢谢你教我如何使用fgets。我试着像你说的那样睡觉,它很有效。 – x4rkz

+0

耶!但是,如果您尝试自动输入二进制文件,您无法修改,我会建议您发布一个新问题,说您要将输入自动化为无法修改的二进制文件。您将以这种方式获得更优雅和强大的答案。 –

5

当执行在shell echo 'blabla' | ./test,壳将启动echo过程和它的标准输出管连接到的./test标准输入管。这与C++无关:这些管道是大多数操作系统的一个特性,几乎每个进程都有它们。

当您的程序执行system时,您正在创建与相同的标准输入管道连接的新进程(或多个进程)。所以,如果有该管(从echo命令)的一些数据尚未阅读test,这将提供给你所开始system的进程读取。

使用echo和管道是提供输入到fgetsscanf的好方法。将数据传递到程序的另一种方法是使用环境变量或命令行参数,但您需要修改代码以检查这些内容。

+0

我知道管道不是C++相关的,我只想自动填充任何语言的scanf,但我想给一个具体的例子。感谢您的解释,但是我们的目标是自动填充scanf并非由我编写的程序,因此使用环境并且修改代码不是一种选择。 – x4rkz

相关问题