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语言从标准输入读取字符,所有非字母字符完全按照输入形式输出,字母字符在输出前加密

C/C++ 服务器,通过标准输入/标准输出与客户端通信(阻塞标准输入,直到读取了多个字节)

C语言入门基础之输入和输出

从标准输出读取的奇怪性能问题

试图从生成的 QProcess 中读取标准输出