C:从标准输出块中读取
Posted
技术标签:
【中文标题】C:从标准输出块中读取【英文标题】:C: popen reading from stdout blocks 【发布时间】:2019-06-08 03:46:50 【问题描述】:The manpage for popen
表示“从“弹出”流中读取命令的标准输出。
但是,我似乎无法在下面的简单程序中获得子进程输出。 “reader”父进程在读取时阻塞(无论是使用fgets
还是fread
)
我错过了什么?
使用 gdb 附加到 pinger 程序表明它正在循环并调用 printf 以输出文本。 fgets
在父母一方没有检测到任何东西......
PINGER.C
#include <string.h>
#include <stdio.h>
#include <unistd.h>
int
main(int argc, char **argv)
int i = 0;
while (1)
printf("stdout %d\n", i++);
sleep(1);
POPENTEST.C
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
int
main(int argc, char **argv)
char *cmd = "./pinger";
printf("Running '%s'\n", cmd);
FILE *fp = popen(cmd, "r");
if (!fp)
perror("popen failed:");
exit(1);
printf("fp open\n");
char inLine[1024];
while (fgets(inLine, sizeof(inLine), fp) != NULL)
printf("Received: '%s'\n", inLine);
printf("feof=%d ferror=%d: %s\n", feof(fp), ferror(fp), strerror(errno));
pclose(fp);
输出
$ ./popenTest
fp open
【问题讨论】:
【参考方案1】:默认情况下,当 stdout 未连接到 tty 时,C 会缓冲写入 stdout。这意味着从操作系统的角度来看,在缓冲区已满或您手动刷新输出之前,程序没有向 stdout 写入任何内容:
#include <string.h>
#include <stdio.h>
#include <unistd.h>
int
main(int argc, char **argv)
int i = 0;
while (1)
printf("stdout %d\n", i++);
fflush(stdout);
sleep(1);
连接到 tty 时,stdout 会在每个换行符上自动刷新。但是当标准输出连接到管道时,不会发生这种自动刷新。
【讨论】:
C 在连接到 tty 时默认也会缓冲写入 stdout,但它是行缓冲而不是块缓冲。 呃,当然可以。谢谢你。在实际情况下,数据源是我无法控制的第 3 方程序,因此缓冲是不可避免的。缓冲区大小是多少? (或如何找出?) @Danny:许多程序接受命令行标志来控制缓冲,这通常是最好的方法。但是,如果你做不到,那么有a few hacks 你可以做。 好主意。实际的程序是ffmpeg
,它有-flush_packets
标志。这应该够了吧。谢谢。
任何关于发现孩子错误的想法将不胜感激。见:***.com/questions/56503915/…以上是关于C:从标准输出块中读取的主要内容,如果未能解决你的问题,请参考以下文章
编写一个从标准输入读取并打印到标准输出的 c 程序,没有内置的行长限制
C语言从标准输入读取字符,所有非字母字符完全按照输入形式输出,字母字符在输出前加密