C语言学生成绩排序程序无法正常打印姓名的问题排查
问题根因
核心故障出在get_name函数的复制逻辑存在C语言未定义行为,导致提取的姓名字符串首字符未被正确写入,最终打印时名字显示为空,看起来像是直接输出了姓氏。
问题代码段如下:
while(line[i] != ' ') name[i] = line[i++];
这段代码在同一条表达式中,既读取i的值作为数组下标,又通过i++修改i的值,C标准没有规定这两个操作的执行顺序,属于典型的未定义写法。在你的编译环境下,实际执行逻辑是先完成i的自增,再给name[i]赋值:所有名字字符都被复制到了name数组偏移1位的位置,name[0]是malloc分配内存时残留的随机值,当这个残留值刚好为'\0'时,整个字符串就会被printf识别为空串。
修复方法
修改get_name函数的循环逻辑,把下标自增拆成独立语句,彻底避免未定义行为,同时增加行尾判断防止越界:
char *get_name(char *line) { int i; char *name = malloc(51); if (name == NULL) exit(71); i = 0; while(line[i] != ' ' && line[i] != '\0') { name[i] = line[i]; i++; } name[i] = 0; return name; }
修改后重新运行即可得到预期输出:
Nombre2 Apellido2 2 Nombre1 Apellido1 8 Nombre3 Apellido3 6
其他鲁棒性优化建议
get_grade函数中的num是局部变量,未初始化时如果遇到格式错误的行可能返回随机值,建议定义时初始化为int num = 0;,提取到成绩后可以直接break跳出循环,无需遍历完一整行。- 所有
fopen调用后需要判断文件指针是否为NULL,处理文件不存在、权限不足的异常场景,避免空指针导致程序崩溃。 get_surname、get_grade的遍历循环中建议增加对'\0'、换行符的判断,避免行格式异常时出现数组越界。
内容的提问来源于stack exchange,提问作者javiLPot
相关产品推荐
相关产品推荐

