C语言从文件读取整数存入数组,打印输出异常乱值
异常输出原因分析
直接导致乱值输出的核心问题
- 文件指针遍历后未复位
你写的逐字符读文件数空格的循环,会把文件指针从文件开头一直移动到文件最末尾。遍历结束后,指针已经停在EOF位置,后续循环调用fscanf时,根本读不到任何文件内的有效整数。
这时候storedData数组是栈上分配的内存,没有被写入任何有效内容,输出的全是栈内存残留的随机值——混杂的0是栈上未被覆盖的清零区域,那些看起来像内存地址的大整数,是之前程序运行残留在栈上的旧调用地址值,和你的文件内容没有任何关系。
举个直观的类比:你把书从头读到尾,书签直接夹在了最后一页的书皮外面,再想翻书找内容,看到的全是书外面的废纸,根本读不到书里的文字。
其他迟早会触发故障的逻辑漏洞
- 统计整数个数的逻辑完全不可靠
你靠数空格数量算数组长度的方式有两个硬伤:- 正常N个整数用空格分隔时,总空格数是
N-1,按这个数值开数组会少存一个元素; - 文件里分隔数字的除了空格还有换行符,如果两个数字之间夹着换行没有空格,统计的空格数会远小于实际整数个数,直接导致数组长度和实际数据量不匹配。
- 正常N个整数用空格分隔时,总空格数是
- 纯C代码混入C++语法
using namespace std;是C++专属语法,标准C语言没有命名空间机制,混写会导致纯C编译环境直接报错。 - 使用已废弃的高危输入函数
gets()不检查输入缓冲区长度,极易触发缓冲区溢出,早已被C标准移除,存在严重安全隐患。 - 文件打开失败的处理逻辑不完整
当fopen返回空指针时,你只打印了错误信息,没有直接退出程序,后续代码会继续对着空文件指针操作,直接触发程序崩溃。 - 栈区数组分配的潜在风险
int storedData[space]是C99支持的变长数组,如果统计出的元素数量很大,直接在栈上分配数组会触发栈溢出,导致程序无提示崩溃。
修正后的核心实现思路
核心调整:跳过不靠谱的空格统计逻辑,读完文件后重置文件指针位置,替换所有高危写法
- 删除多余的C++语法
using namespace std; - 把
gets(FILENAME)替换为fgets(FILENAME, sizeof(FILENAME), stdin);,手动移除读入字符串末尾附带的换行符 - 文件打开失败的判断分支里,打印错误后直接加
return 1;退出,不执行后续文件操作 - 第一次遍历文件统计元素个数时,直接调用
fscanf(fptr, "%d", &tmp),根据函数返回值判断是否读到了有效整数,读到一个就累加计数,不再靠数空格算个数 - 统计完总元素个数后,调用
rewind(fptr);把文件指针强制重置到文件开头 - 循环将文件中的整数读入数组时,每次都判断
fscanf的返回值,确认读取成功再存入数组
内容的提问来源于stack exchange,提问作者Infinitypool
相关产品推荐
相关产品推荐

