如何读取文件中学生信息并通过结构体处理?代码问题求助
问题分析与修正方案
先梳理你代码里的几个问题:
_CRT_SECURE_NO_WARNINGS定义位置错误,必须放在所有头文件包含之前,否则无法禁用VS的安全警告。- 文件打开失败后没有终止程序,后续代码会继续操作空指针
ptr,直接导致崩溃。 - 分割字符串的分隔符定义错误:
const char s[1] = " ";字符串常量默认带结束符\0,数组大小至少要设为2,改成const char* s = " ";更稳妥。 - 文件打开前那行
token = strtok(str, s);完全多余,此时str未初始化,属于未定义行为。 - 没实现按分数升序排序的核心需求,原代码只是读取后直接输出。
- 硬编码输出三个分数,要是学生数量变化直接出错,应该用循环遍历输出。
- 没处理文件里的空行(比如你文件开头的空行),读取空行后strtok会返回NULL,执行strcpy时会操作空指针导致崩溃。
修正后的代码
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> // 排序用的比较函数,qsort需要 int compareMarks(const void* a, const void* b) { const struct student* s1 = (const struct student*)a; const struct student* s2 = (const struct student*)b; return s1->mark - s2->mark; // 返回值为正就交换,实现升序排序 } int main() { const int N = 3; int i = 0; struct student { char surname[50]; int mark; }; struct student PI1[N]; char str[50]; const char* s = " "; char* token; FILE* ptr = fopen("test.txt", "r"); if (NULL == ptr) { printf("文件无法打开\n"); return 1; // 打开失败直接终止程序 } while (fgets(str, 50, ptr) != NULL && i < N) { // 跳过空行 if (str[0] == '\n' || str[0] == '\r') { continue; } // 分割字符串并处理无效行 token = strtok(str, s); if (token == NULL) { continue; } strcpy(PI1[i].surname, token); token = strtok(NULL, s); PI1[i].mark = token ? atoi(token) : 0; // 处理无分数的情况 i++; } fclose(ptr); // 按分数升序排序 qsort(PI1, i, sizeof(struct student), compareMarks); printf("按分数升序排列的成绩:\n"); // 循环输出,避免硬编码 for (int j = 0; j < i; j++) { printf("%d ", PI1[j].mark); } printf("\n"); return 0; }
关键修正说明
- 调整
_CRT_SECURE_NO_WARNINGS位置,确保生效。 - 文件打开失败后直接终止程序,避免后续错误操作。
- 修正分隔符定义,避免字符串截断问题。
- 增加空行、无效行的处理逻辑,防止崩溃。
- 使用标准库
qsort实现结构体按分数升序排序,适配通用排序需求。 - 改用循环输出,适配不同的学生数量(只要不超过预设的N)。
内容的提问来源于stack exchange,提问作者KonstantaV
相关产品推荐
相关产品推荐

