C语言学生管理程序新增学生后无法正常读取问题求助
C程序新增学生后列表显示为空的问题解决
核心问题:数组索引错误
初始学生数量sl=2,对应数组索引0和1的元素。执行add命令时,你先执行了sl++(此时sl=3),接着把新学生信息存入students[sl](即索引3),但调用list函数时循环范围是i<sl(也就是i=0、1、2),索引2的元素根本没被赋值,所以显示为空字符串和0值。
正确逻辑是:先把新学生存入当前最后一个元素的下一位(用当前sl作为索引),再自增sl。
关键代码修正
把add分支的代码调整如下:
else if(!strcmp(process,"add")) { str name,surname,year,no; printf("\n name: "); gets(name); printf("\n surname: "); gets(surname); printf("\n year: "); gets(year); printf("\n no: "); gets(no); // 用当前sl作为新元素的索引(此时sl是已有学生数,对应数组下一个空位置) strcpy(students[sl].name,name); strcpy(students[sl].surname,surname); students[sl].no = atoi(no); students[sl].year = atoi(year); printf("%s %d",name,atoi(no)); // 最后再增加学生计数 sl++; }
其他潜在问题修复
- list函数声明冗余:原声明
void list(Student[2],int sn);中的[2]无意义,应改为void list(Student*, int sn);,和函数定义保持一致。 - gets函数不安全:gets已被C标准废弃,容易引发缓冲区溢出,建议用
fgets替代并处理换行符:printf("\n name: "); fgets(name, sizeof(name), stdin); name[strcspn(name, "\n")] = '\0'; // 去掉fgets读取的换行符 - 字符串拼接溢出:原代码
str out = "not known command: ";初始化的数组长度刚好等于字面量长度,strcat(out, process)会导致缓冲区溢出,应初始化足够大的数组:char out[100] = "not known command: "; strcat(out, process); puts(out); - 未初始化变量:
str process;未初始化就调用strcmp(process,"exit")会触发未定义行为,应初始化为空字符串:str process = "";
修正后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> typedef char str[50]; typedef struct{ str name; str surname; int year; int no; }Student; void list(Student*, int sn); int main() { Student students[100] = { {"samuel","any",20,111}, {"veronica","suqal",25,87} }; int sl = 2; puts("list, add, exit"); puts("------------------------\n"); str process = ""; while(strcmp(process,"exit")) { fgets(process, sizeof(process), stdin); process[strcspn(process, "\n")] = '\0'; if(!strcmp(process,"list")) list(students,sl); else if(!strcmp(process,"add")) { str name,surname,year,no; printf("\n name: "); fgets(name, sizeof(name), stdin); name[strcspn(name, "\n")] = '\0'; printf("\n surname: "); fgets(surname, sizeof(surname), stdin); surname[strcspn(surname, "\n")] = '\0'; printf("\n year: "); fgets(year, sizeof(year), stdin); year[strcspn(year, "\n")] = '\0'; printf("\n no: "); fgets(no, sizeof(no), stdin); no[strcspn(no, "\n")] = '\0'; strcpy(students[sl].name,name); strcpy(students[sl].surname,surname); students[sl].no = atoi(no); students[sl].year = atoi(year); printf("%s %d\n",name,atoi(no)); sl++; } else if(!strcmp(process,"exit")) { puts("-------exiting--------"); } else { char out[100] = "not known command: "; strcat(out,process); puts(out); } } return 0; } void list(Student* students,int sn) { for(int i=0;i<sn;i++) { Student std = students[i]; printf("student: \n name: %s, surname: %s, years: %d, no: %d \n",std.name,std.surname,std.year,std.no); } }
内容的提问来源于stack exchange,提问作者user21245217
相关产品推荐
相关产品推荐

