You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将stdout和stderr重定向至不同进程:C程序stdout无输出问题

问题分析与解决

为什么stderr无需fflush就能输出?

C标准库中stdout和stderr的默认缓冲策略存在差异:

  • stderr默认采用无缓冲(部分实现为行缓冲),所有写入操作会立即输出到目标设备,不需要手动调用fflush。
  • stdout在连接终端时是行缓冲(遇到换行符自动刷新),但当它被重定向到管道时,会自动切换为全缓冲——只有缓冲区被填满或程序退出时才会刷新输出。你的程序循环输出但未填满缓冲区,导致stdout内容一直滞留在缓冲里,无法被后续sed进程读取。

无需手动插入fflush的解决办法

1. 代码中修改stdout的缓冲模式

在程序开头添加代码,将stdout设置为无缓冲或行缓冲:

  • 设置无缓冲(和stderr行为一致):
#include <stdio.h>

int main()
{
    setvbuf(stdout, NULL, _IONBF, 0); // 关闭stdout缓冲
    while (1)
    {
        fprintf(stdout, "stdout: sias\n");
        fprintf(stderr, "stderr: cias\n");
        sleep(5);
    }
    return 0;
}
  • 设置行缓冲(你的输出每行带\n,换行时自动刷新):
setvbuf(stdout, NULL, _IOLBF, 0); // 将stdout设为行缓冲

2. 用stdbuf命令强制修改缓冲(无需改代码)

运行程序时通过stdbuf工具强制设置stdout的缓冲模式,比如行缓冲:

{ stdbuf -oL tss 2>&1 1>&3 3>&- | sed -u 's/^/err: /'; } 3>&1 1>&2 | sed -u 's/^/out: /'

-oL表示将stdout设为行缓冲,-o0可设为无缓冲,这种方式无需修改C代码,适合快速测试。

3. 编译时设置相关选项(兼容性有限)

部分编译器提供编译选项修改默认缓冲行为,比如GCC结合-D_GNU_SOURCE宏,但这种方式兼容性较差,不如前两种方法通用。

内容的提问来源于stack exchange,提问作者user180574

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 04:05:26