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

C语言管道传递输出前如何统计字节数并存入文本文件

问题排查与修复方案

现有代码的核心问题

  • 读取逻辑错误:getc(stdout) 本身是无效操作,stdout 是输出流,无法从中读取数据,这是字节数始终统计为0的直接原因。且统计逻辑放在命令执行之前,完全拿不到目标命令的输出内容。
  • 文件写入模式错误:使用"w"模式打开统计文件,每次打开都会清空文件原有内容,自然只会保留最后一次写入的记录。
  • 逻辑时序错误:现有逻辑是先统计、再执行命令,完全没有把命令输出和统计、管道传递关联起来,无法实现“统计后再把输出传给下一级管道”的需求。

修复思路

每个管道阶段的子进程需要按如下逻辑调整:

  1. 新建管道捕获当前命令的执行输出
  2. 读取管道中的内容,同步统计字节数并把内容原封不动转发到标准输出,传给下一级管道
  3. 统计完成后用追加模式写入统计文件,避免覆盖之前的记录

参考实现代码

#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>

// 每个管道阶段的子进程执行逻辑
void run_command(int i, char* tabCommande[]) {
    int pipe_fd[2];
    if (pipe(pipe_fd) == -1) error_and_exit();

    pid_t cmd_pid = fork();
    if (cmd_pid == -1) error_and_exit();

    if (cmd_pid == 0) {
        // 子进程执行目标命令,输出重定向到管道写端
        close(pipe_fd[0]);
        dup2(pipe_fd[1], STDOUT_FILENO);
        close(pipe_fd[1]);
        execlp("/bin/sh", "sh", "-c", tabCommande[i], (char *)NULL);
        error_and_exit();
    } else {
        // 父进程读管道内容,统计+转发
        close(pipe_fd[1]);
        int bytes = 0;
        char buf[4096];
        ssize_t n;

        // 用a模式打开文件追加写入,不会覆盖历史记录
        FILE *f = fopen("count.txt", "a");
        if (!f) error_and_exit();

        while ((n = read(pipe_fd[0], buf, sizeof(buf))) > 0) {
            bytes += n;
            // 原内容转发到标准输出,传递给下一级管道
            write(STDOUT_FILENO, buf, n);
        }
        close(pipe_fd[0]);
        waitpid(cmd_pid, NULL, 0);

        fprintf(f, "%d : %d\n", i, bytes);
        fclose(f);
        exit(0);
    }
}

补充说明

如果要求统计记录严格按照管道阶段的顺序写入,需要额外增加同步逻辑:比如所有子进程将统计结果通过IPC发给主进程,主进程统一按顺序写入文件,避免多进程并行执行导致的写入顺序乱序问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 18:36:00