管道左侧程序无输出时右侧程序出现异常输出的原因是什么?
问题根因
这个问题完全是你的代码逻辑缺陷导致的,和Shell、管道机制没有关系,核心是触发了C语言的未定义行为,详细推导如下:
- 管道
./a | ./b的作用仅为将程序a的标准输出重定向到程序b的标准输入,程序a的标准输入仍然绑定当前终端,你输入的所有内容都被a的scanf读取,a全程没有向标准输出写入任何数据就直接退出。 - 程序b的标准输入对应的管道读端,会因为a的标准输出关闭触发EOF,此时b调用
scanf("%s", s)会直接读取失败,返回值为EOF,不会对你定义的s数组做任何修改。 - 你在b中定义的
char s[255]是栈上的局部变量,没有做初始化操作,数组内的内容是栈内存的残留垃圾值。你当前运行环境下,这块内存的开头恰好是0x40(对应ASCII 64)、0x03(对应ASCII 3)、紧跟\0字符串结束符,所以遍历输出的时候会固定得到这两个值。如果更换编译选项、操作系统甚至多运行几次,输出的内容都可能发生变化。
验证方案
你可以给程序b的数组加上初始化逻辑:
char s[255] = {0};
或是加上输入合法性判断,避免访问未初始化的内存:
if (scanf("%s", s) != 1) { // 读取失败直接退出,不访问s数组 return 1; }
修改后再运行./a | ./b,程序b就不会再输出异常的ASCII码了。
内容的提问来源于stack exchange,提问作者yztz
相关产品推荐
相关产品推荐

