#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如何做呢?
解决方法
这有点奇怪,这使得* 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标准库来到操作系统的缓冲区,然后是磁盘的正确.
现在你的问题:用于存储要写入的字符的标准库缓冲区在程序的内存空间中.尽管出现了这些数据,但数据尚未离开您的程序,因此其他程序无法正式访问.我觉得你没有运气.你并不孤单:当一个人试图通过管道操作它们时,大多数交互式控制台程序将会执行得很好.