c – 如何读取未刷新的进程输出?

考虑这个小程序被编译为application.exe
#include <stdio.h>

int main()
{
    char str[100];
    printf ("Hello,please type something\n");
    scanf("%[^\n]s",&str);
    printf("you typed: %s\n",str);
    return 0;
}

现在我使用这个代码来启动application.exe并获取它的输出.

#include <stdio.h>
#include <iostream>
#include <stdexcept>

int main()
{
    char buffer[128];
    FILE* pipe = popen("application.exe","r");
    while (!feof(pipe)) {
        if (fgets(buffer,128,pipe) != NULL)
            printf(buffer);
    }
    pclose(pipe);
    return 0;
}

我的问题是,直到我做了我的输入,没有输出.然后两条输出线都被取出.
我可以通过在第一个printf语句之后添加这行来解决这个问题.

fflush(stdout);

那么在我按预期的方式进行输入之前,第一行被提取.

但是如何获取我不能修改的应用程序的输出,并且在“实时”中不使用fflush()(意味着退出之前)? .
而Windows cmd如何做呢?

解决方法

您被C程序自动打开的流的缓冲随附加的设备类型而变化的事实一直被咬住.

这有点奇怪,这使得* nixes很好玩(这反映在C标准库中)的一个事情是,进程并不在意他们从哪里获取数据以及写入它们的位置.你只需管理和重定向在你的休闲,它通常是即插即用,而且相当快.

这个规则破坏的一个明显的地方是互动;你提出了一个很好的例子.如果程序的输出是块缓冲的,那么在可能存在4k数据累积之前看不到它,否则进程退出.

程序可以检测它是否通过isatty()(也可能通过其他方式)写入终端.终端概念上包括用户,建议交互式节目.打开stdin和stdout的库代码检查并将缓冲策略更改为行缓冲:当遇到换行符时,流将被刷新.这是完美的交互式,面向线性的应用程序. (它不如bash所做的那样完美的线条编辑,完全禁用缓冲.)

open group man page for stdin在缓冲方面相当模糊,以便实现足够的余地来实现高效,但它确实说:

the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device.

这就是你的程序发生了什么:标准库看到它正在运行“非交互式”(写入一个管道),试图做到智能高效并且开启块缓冲.编写换行符不再刷新输出.通常这是一件好事:想象一下,写入二进制数据,平均每256个字节写入磁盘!可怕.

值得注意的是,您可以在一个磁盘之间可能存在一系列缓冲区;之后C标准库来到操作系统的缓冲区,然后是磁盘的正确.

现在你的问题:用于存储要写入的字符的标准库缓冲区在程序的内存空间中.尽管出现了这些数据,但数据尚未离开您的程序,因此其他程序无法正式访问.我觉得你没有运气.你并不孤单:当一个人试图通过管道操作它们时,大多数交互式控制台程序将会执行得很好.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...