使用fgetc()读取文件后字符串出现未定义字符的问题排查
问题分析与修复方案
你遇到的未定义字符问题主要有几个核心原因,咱们一步步拆解:
1. 初始变量未初始化,循环逻辑错误
你的代码里int c , i = 0 ;只初始化了i,c的初始值是随机的,第一次进入while(c != EOF)判断时,c可能刚好等于EOF导致循环直接跳过,或者进入循环后才第一次读取输入,逻辑顺序完全不对。
2. 把EOF存入了数组
当fgetc(stdin)返回EOF时,你依然把它赋值给str[i],而EOF的数值是-1,对应到char类型(如果是有符号char的话)是一个非打印的非法字符,这会直接污染你的字符串内容。
3. 字符串缺少终止符'\0'
C语言中,printf("%s")完全依赖字符串末尾的'\0'来确定结束位置,如果没有这个标记,它会一直读取数组后面的内存,直到遇到随机的空字符,这就是你看到“未定义字符”的核心原因。
4. 未处理数组越界
当输入内容超过1024字符时,i会继续增长,超出数组str[1024]的范围,导致内存溢出,触发更严重的未定义行为。
修正后的代码
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> int main(int argc, char *argv[]){ int c; int i = 0; // 预留一个位置给字符串终止符 char str[1024]; // 先读取字符再判断是否为EOF,避免初始值问题 while((c = fgetc(stdin)) != EOF) { // 检查数组剩余空间,留最后一个位置存'\0' if (i < 1023) { str[i] = c; i++; } else { // 可选:处理输入过长的情况,比如提示用户 fprintf(stderr, "输入内容过长,已截断\n"); break; } } // 手动添加字符串终止符,这是解决乱码的关键 str[i] = '\0'; printf("%s\n", str); return 0; }
关键修改说明:
- 调整循环顺序:先执行
c = fgetc(stdin)再判断是否为EOF,既避免了初始c未定义的问题,也不会把EOF存入数组。 - 添加数组越界检查:确保
i最大到1023,留最后一个位置给'\0',彻底防止内存溢出。 - 手动添加终止符:循环结束后给
str[i]赋值'\0',让printf能正确识别字符串的结束位置,不会读取额外的内存内容。
这样修改后,你再执行test < file.json就不会出现未定义字符了。
内容的提问来源于stack exchange,提问作者Haskell-newb
相关产品推荐
相关产品推荐

