C语言课程记录程序:基于结构体数组的文件读写实现方法
Lessons简易课程记录程序实现参考
先修正你现有代码的编译错误
你当前写的结构体定义存在多处语法问题,直接编译会报错,修正后的正确代码如下:
// 修正后的结构体定义:原代码的"typed"是"typedef"的笔误,成员分隔符为分号不是逗号 typedef struct lessons{ char LessonName[30]; char TeacherName[20]; char TeacherLastName[20]; int numberOfStudents; } Lessons; // 静态结构体数组,最大存储10条记录 Lessons info[10]; // 全局计数变量:记录当前数组中存了多少条有效课程 int current_record_count = 0;
关于存储逻辑的选择
- 完全不需要你手动提前创建txt文件写入初始内容。正常的程序逻辑会在启动时自动检查指定的存储文件是否存在,不存在就自动创建空文件,全程不需要用户手动介入文件操作。
- 核心逻辑是 内存中的数组是临时数据,磁盘上的文件是永久存储:只要内存里的课程数据有变动(比如新增了一条记录),就立刻把当前的全部有效数据同步写入文件,不管程序是正常退出还是意外崩溃,文件里的内容都是最新的,下次启动程序时再把文件内容读回内存数组即可。
- 两种存储格式的适配场景:
txt文本格式:和你给出的示例格式匹配,人可以直接打开文件查看、编辑内容,解析逻辑简单,非常适合初学者练手。bin二进制格式:读写速度更快,但文件内容是不可读的乱码,适合存储大规模数据,初学阶段优先实现txt格式的逻辑即可。
新记录存入静态数组的实现逻辑
你用的是固定长度的静态结构体数组,没有动态扩容能力,整个新增流程非常直白,没有复杂逻辑:
- 收到新增指令后,首先判断
current_record_count是否已经达到数组最大长度10,如果是,直接提示“最多支持存储10门课程,无法新增”,结束操作。 - 依次引导用户输入4个字段:课程名、老师名、老师姓、选课人数。
- 把用户输入的全部内容,赋值到
info[current_record_count]对应的结构体成员中。 - 赋值完成后把
current_record_count加1,代表数组新增了一条有效记录。
对应的新增功能代码参考:
void add_new_lesson() { if (current_record_count >= 10) { printf("最多存储10门课程,无法继续新增\n"); return; } Lessons new_record; printf("请输入课程名:"); scanf("%s", new_record.LessonName); printf("请输入老师的名:"); scanf("%s", new_record.TeacherName); printf("请输入老师的姓:"); scanf("%s", new_record.TeacherLastName); printf("请输入选课学生人数:"); scanf("%d", &new_record.numberOfStudents); // 把新记录存入数组 info[current_record_count] = new_record; current_record_count++; }
文件读写的实现逻辑
写入文件(把内存数组内容持久化)
不管是新增完课程、还是程序准备退出,都调用这个函数,把数组里的全部有效记录按示例格式逐行写入文件:
void save_records_to_file() { // 用"w"模式打开文件,会覆盖原有内容,写入最新的全量数据 FILE* fp = fopen("lessons_record.txt", "w"); if (fp == NULL) { printf("文件打开失败,无法保存记录\n"); return; } for (int i = 0; i < current_record_count; i++) { fprintf(fp, "%s %s %s %d\n", info[i].LessonName, info[i].TeacherName, info[i].TeacherLastName, info[i].numberOfStudents ); } fclose(fp); }
读取文件(把磁盘数据读回内存数组)
程序启动时调用这个函数,逐行解析文件里的每条记录,填充到内存数组中:
void load_records_from_file() { // 用"r"模式打开文件读取内容,如果文件不存在会返回NULL FILE* fp = fopen("lessons_record.txt", "r"); if (fp == NULL) { // 文件不存在就自动创建一个空文件 fp = fopen("lessons_record.txt", "w"); fclose(fp); current_record_count = 0; return; } current_record_count = 0; // 逐行读取,直到文件结束 while (fscanf(fp, "%s %s %s %d", info[current_record_count].LessonName, info[current_record_count].TeacherName, info[current_record_count].TeacherLastName, &info[current_record_count].numberOfStudents ) != EOF) { // 避免读入的内容超出数组最大容量 if (current_record_count < 10) { current_record_count++; } else { break; } } fclose(fp); }
串起全流程的主函数示例
int main() { // 程序启动时先加载文件里的历史记录 load_records_from_file(); int op; while(1) { printf("\n===== 课程记录管理 =====\n"); printf("1. 新增课程记录\n"); printf("2. 查看所有课程记录\n"); printf("3. 退出程序\n"); printf("请输入操作选项:"); scanf("%d", &op); if (op == 1) { add_new_lesson(); // 新增完成立刻同步到文件 save_records_to_file(); } else if (op == 2) { // 遍历数组输出所有记录 for (int i = 0; i < current_record_count; i++) { printf("%s %s %s %d\n", info[i].LessonName, info[i].TeacherName, info[i].TeacherLastName, info[i].numberOfStudents ); } } else if (op == 3) { // 退出前再做一次全量保存,避免数据丢失 save_records_to_file(); break; } } return 0; }
内容的提问来源于stack exchange,提问作者Mantas
相关产品推荐
相关产品推荐

