首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当我使用c++时,会发生什么?

当我使用c++时,会发生什么?
EN

Stack Overflow用户
提问于 2015-09-01 16:22:43
回答 2查看 145关注 0票数 3

我有一个非常简单的程序:

代码语言:javascript
运行
复制
void main()
{
    fgets(buf,133,stdin);
    printf( buf);
    system("/bin/dash");
}

当我启动程序时,一切都很好,我可以键入任何我想要的,然后我有一个外壳。不过,如果我做了

代码语言:javascript
运行
复制
$ echo 'blabla' | ./test

为了自动填充buf (不使用键盘输入anyting ),可以执行shell,例如,/bin/ls可以正常工作。(很明显,显示命令工作正常)

如果删除fget行,并执行相同的命令,它将工作,但将'blabla‘作为/bin/dash的参数。但是,添加nul字符或返回'\xd‘以模拟我的键盘在fget中的返回是行不通的。

我想了解,当我在我的c++程序中使用‘\’符号时,会发生什么。我认为这是自动填充扫描和fget的解决方案,而不需要任何人的交互,我是做错了还是有其他的解决方案?

谢谢。

Debian,C++ g++

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-01 17:14:29

如果我正确地理解了您,您希望同时向您的fgets和您的shell提供输入,但是却发现当您管道时,shell没有接收到任何输入。

这是因为libc将为fgets缓冲输入数据。

它不是读取blabla\n中的7个字节,而是将其余的字节传递给shell,而是读取高达4096字节(系统依赖的),并将其余的4089字节用于stdin上的未来fgets/f*调用。这些数据将存储在程序内部,不能用于从底层流读取的其他进程,如调用的shell。

当您以交互方式运行并在键盘上键入时,当您点击enter时,只有7个字节可用,因此缓冲区只填充了7个字节。因此,您键入的其余数据对shell是可用的。您本可以在您的buggy程序中模拟同样的效果,在输入中有策略地放置延迟:

代码语言:javascript
运行
复制
{ echo "for fgets"; sleep 1; echo "ls"; } | ./foo

您可以通过将缓冲区大小设置为1字节来避免此问题,这样fgets就不会读取超过必要的内容:

代码语言:javascript
运行
复制
#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");
}

现在,您可以使用管道运行它了,并且没有任何延迟:

代码语言:javascript
运行
复制
$ 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
票数 2
EN

Stack Overflow用户

发布于 2015-09-01 16:38:21

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

当您的程序执行system时,您将创建一个连接到同一标准输入管道的新进程(或多个进程)。因此,如果管道中有一些数据(来自echo命令)没有被test读取,则可以通过您使用system启动的进程读取数据。

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

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32336522

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档