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

将C程序通过管道自身串联后,输入Ctrl-D为何输出四次重复内容?

为什么./e52 | ./e52会输出四次重复?

这问题挺有意思的,我来帮你一步步拆解清楚:

先明确你的程序逻辑

你的程序e52.c的核心逻辑很简单:

  • 每次从输入读取一个字符
  • 先输出这个字符一次
  • 如果字符不是换行符,再输出一次
    所以正常情况下,输入一个字符(比如1),会得到两次重复的输出(11),这和你用cat passwd.copy | ./e52时的表现完全一致。

两种管道场景的差异

场景1:cat passwd.copy | ./e52

这里cat把文件内容一次性输出到管道,作为e52的输入:

  • e52逐个读取文件里的每个字符,每个字符都输出两次
  • 当cat读完文件后,会关闭管道的写端,e52读到EOF(-1),因为你的循环条件是ch > 0,-1不满足条件,循环直接退出,程序结束。最终结果就是文件里的每个字符都被重复一次,符合预期。

场景2:./e52 | ./e52

这是两个e52程序通过管道串联,第一个的输出作为第二个的输入,完整流程是这样的:

  1. 第一个e52从终端标准输入读取内容,所以它会等待你输入字符(这就是你看到的“等待输入”)
  2. 你输入1然后按Ctrl-D(发送EOF信号):
    • 第一个e52读取到1,输出两次变成11,然后读到EOF,循环退出,第一个程序结束并关闭管道写端
    • 第二个e52此时开始读取管道里的内容——也就是第一个程序输出的11
    • 第二个e52对这两个1分别处理:每个1都输出两次,所以第一个1变成11,第二个1也变成11,合起来就是1111,也就是四次重复
  3. 当第二个e52读完管道里的所有内容,读到EOF,循环退出,程序结束。

额外的小建议

你的程序里有个潜在的问题:getchar()的返回值是int类型(因为它需要返回EOF这个特殊值,对应-1),但你把它赋值给了char ch。如果你的系统中char是无符号类型,那么-1会被转换成255,这时候ch > 0的条件会永远成立,导致程序进入死循环。

建议把代码改成更规范的写法:

/* Saved as e52.c */
#include <stdio.h>
int main() {
    int ch; // 改成int类型,适配getchar的返回值
    while ((ch = getchar()) != EOF) { // 用EOF判断结束,逻辑更可靠
        putchar(ch);
        if (ch != '\n') putchar(ch);
    }
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:49:34