C语言学生数据库文件处理无法阻止重复ID输入问题求助
问题修复说明
核心问题
- 读写格式不匹配:你使用
fread()读取二进制结构体数据,但写入时用fprintf()输出纯文本内容,两种格式完全不兼容,fread()无法从文本内容中解析出正确的struct student结构体数据,导致ID重复校验逻辑完全失效。 - 文件指针位置错误:
a+模式打开文件时,指针默认指向文件末尾,直接调用fread()会从末尾开始读取,无法拿到已存储的学生数据,重复校验的循环永远不会执行。 - 潜在安全问题:
scanf("%s")未限制输入长度,易触发缓冲区溢出;strncpy()在源字符串长度等于目标数组长度时不会自动补终止符'\0',可能导致字符串越界访问。
修复方案(保持文本存储格式)
struct student { char id[20]; char name[20]; char branch[20]; }; void insert_student() { FILE *fp1; struct student rcd; fp1 = fopen("students.dat", "a+"); if (fp1 == NULL) { printf("Students data does not exists\n"); return; } char id[20]; char name[20]; char branch[20]; printf("\nEnter Student ID: "); scanf("%19s",id); // 限制输入长度避免溢出 getchar(); // 打开后先把文件指针移到开头才能读已存数据 rewind(fp1); char read_buf[100]; int id_exist = 0; // 改为按文本行读取解析ID while (fgets(read_buf, sizeof(read_buf), fp1) != NULL) { if (strncmp(read_buf, "ID: ", 4) == 0) { char exist_id[20]; sscanf(read_buf + 4, "%19s", exist_id); if(strcmp(exist_id, id) == 0) { printf("\nStudent with ID %s already exists !\n",id); id_exist = 1; break; } } } if (id_exist) { fclose(fp1); return; } printf("\nEnter Student Name: "); scanf("%19s",name); printf("\nEnter Student Branch :"); scanf("%19s",branch); // 手动补字符串终止符 strncpy(rcd.id, id, 19); rcd.id[19] = '\0'; strncpy(rcd.name, name, 19); rcd.name[19] = '\0'; strncpy(rcd.branch, branch, 19); rcd.branch[19] = '\0'; fprintf(fp1, "Name =%s\n", rcd.name); fprintf(fp1, "ID: %s\n", rcd.id); fprintf(fp1, "Branch: %s\n", rcd.branch); fprintf(fp1, "-------------\n\n"); fclose(fp1); return; }
可选方案(二进制读写)
如果你希望用fread()/fwrite()的二进制读写模式,把写入逻辑替换为fwrite(&rcd, sizeof(struct student), 1, fp1)即可,不需要再用fprintf()写文本格式,同时注意打开文件时使用ab+模式。
内容的提问来源于stack exchange,提问作者Adarsh Singh
相关产品推荐
相关产品推荐

