微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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标准库来到操作系统的缓冲区,然后是磁盘的正确.

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

原文地址:https://www.jb51.cc/c/114672.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐