C语言程序读取学生信息写入文件时出现乱码与零值的原因及修复方法
问题分析与修复方案
别担心,咱们一步步拆解你代码里的问题,搞清楚为什么会输出奇怪符号和零值,然后把它修好:
导致数据异常的核心原因
你的代码里有几个关键错误,直接引发了读写数据的错乱:
重复打开文件+错误的打开失败判断
你先执行了fpt = fopen("project1.txt", "r");,接着又在if条件里重新打开了一次文件,这完全多余。更重要的是,fopen失败时返回的是NULL,不是EOF,所以你的错误判断根本不会触发——就算输入文件打不开,程序也会硬着头皮继续执行,后续读取操作自然会乱套。格式符与变量类型不匹配
你定义的成绩变量都是double类型,但fscanf里用了%f格式符,这个格式符是给float类型用的。读取double必须用%lf,格式符不匹配会直接导致内存读写错乱,输出时就会出现奇怪的数值或者零值。数组下标错误+多余的取地址符
C语言数组下标从0开始,你的循环从i=1到i<=68,会跳过第一个元素的位置;另外,name[i]和id[i]本身就是指向字符数组首地址的指针,fscanf里不需要加&,加了之后传递的是指针的地址,类型不匹配会导致姓名和学号读取异常,输出奇怪符号。未检查输出文件的打开状态
你只检查了输入文件,但如果result1.txt因为权限或路径问题打不开,frt会是NULL,后续的fprintf操作直接会出错。不规范的main函数声明
标准C要求main函数必须声明为int main(),并且最后要返回0,你的main()不符合标准,可能引发一些未定义行为。
修复后的完整代码
#include <stdio.h> #include <stdlib.h> int main() { double t1[100], t2[100], t3[100], hw1[100], hw2[100], hw3[100], hw4[100], prj[100]; char name[100][50]; char id[100][8]; int i; FILE *fpt = NULL; FILE *frt = NULL; // 仅打开一次输入文件,并判断是否成功 fpt = fopen("project1.txt", "r"); if (fpt == NULL) { printf("ERROR, can't open input file\n"); return 1; // 打开失败直接退出,避免后续错误操作 } // 打开输出文件,同时检查状态 frt = fopen("result1.txt", "w"); if (frt == NULL) { printf("ERROR, can't open output file\n"); fclose(fpt); // 记得关闭已经打开的输入文件,避免资源泄漏 return 1; } printf("Please refer to result text file to see the result. Thank you\n"); // 数组从0开始循环,读取68条数据 for (i = 0; i < 68; i++) { // name[i]和id[i]无需加&,double类型用%lf读取 fscanf(fpt, "%s%s%lf%lf%lf%lf%lf%lf%lf%lf", name[i], id[i], &t1[i], &t2[i], &t3[i], &hw1[i], &hw2[i], &hw3[i], &hw4[i], &prj[i]); // 优化输出格式,让内容对齐更整齐 fprintf(frt, "%-15s %-8s %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\n", name[i], id[i], t1[i], t2[i], t3[i], hw1[i], hw2[i], hw3[i], hw4[i], prj[i]); } // 关闭文件,释放资源 fclose(fpt); fclose(frt); system("pause"); return 0; // main函数返回0表示正常退出 }
修复点说明
- 修正文件打开逻辑:只打开一次输入文件,用
NULL判断打开状态,失败时直接退出并关闭已打开的资源;同时新增输出文件的打开检查。 - 格式符匹配修正:
fscanf中用%lf读取double类型变量,保证数据读取准确。 - 数组与传参修正:循环从
i=0开始,移除name[i]和id[i]前的&,确保字符串读取正确。 - 规范main函数:改为标准的
int main(),最后返回0,符合C语言标准。 - 优化输出格式:用
%-15s和%-8s让姓名、学号左对齐且占固定宽度,%.2f控制成绩保留两位小数,输出更整齐易读。
内容的提问来源于stack exchange,提问作者Tom Cruise




