读取bin文件提取可打印字符时printf随机重复输出问题排查
问题核心原因
- 重复输出的直接原因是代码同时做了两次打印:每读到一个可打印字符就调用
putchar(ch)输出一次,等凑够指定长度l后又调用printf("%s", buffer)把整段字符再打印一遍,自然会出现重复内容 - 赋值逻辑错误:
buffer[i] = putchar(ch)的写法不符合预期,你本意是把读到的可打印字符ch存入缓冲区,实际却是先把ch输出到终端,再把putchar的返回值赋值给缓冲区,属于逻辑完全走偏 - 输出非预期/需要fflush才能正常显示是因为标准输出
stdout默认是行缓冲模式,只有遇到换行符、缓冲区满或者主动调用fflush的时候才会把缓冲区内容刷到终端,你没加换行的时候内容就会滞留在输出缓冲区里,看起来像是没输出或者输出时机不对
修复后的代码
#include <stdio.h> #include <stdlib.h> int main(int argc, char** argv) { int l = 3; if(argc >= 2){ l = atoi(argv[1]); } char* buffer = (char*) malloc((l + 1) * sizeof(char)); int ch; int i = 0; while ((ch=getchar()) != EOF) { if (ch >= ' ' && ch <= '~') { buffer[i] = ch; i++; // 凑够长度就输出 if (i == l) { buffer[i] = '\0'; printf("%s\n", buffer); i = 0; } } else { // 遇到不可打印字符,先输出缓冲区里剩余的内容 if (i > 0) { buffer[i] = '\0'; printf("%s\n", buffer); i = 0; } } } // 处理最后剩下的不足长度的可打印字符 if (i > 0) { buffer[i] = '\0'; printf("%s\n", buffer); } free(buffer); return 0; }
关键修改点
- 移除了多余的
putchar调用,仅在凑够长度或者遇到不可打印字符时统一输出缓冲区内容,避免重复打印 - 缓冲区直接存储读取到的
ch,不再错误使用putchar的返回值赋值 - 调整了判断顺序,先判断字符是否可打印,再判断是否凑够长度输出,避免逻辑错位
- 输出时添加换行符,利用标准输出的行缓冲特性自动刷出内容,不需要手动调用
fflush(stdout) - 新增了循环结束后剩余内容的输出逻辑,避免最后一段不足长度的可打印字符丢失
- 补充了堆内存释放,避免内存泄漏
内容的提问来源于stack exchange,提问作者Adam Frkal
相关产品推荐
相关产品推荐

