You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C语言中通过文件处理验证学生ID输入的问题排查

学生ID重复验证功能异常排查与修复

问题场景

  • 功能需求:添加学生时需验证ID唯一性,若ID已存在则禁止重复添加
  • 异常现象:尝试添加ID为2016的学生时,系统错误提示该ID已存在(实际文件中仅存ID为2015的学生)

原代码

void add_student(){
        int isFound = 0;
            FILE *fp;  // to open a file, fopen, fclose.
            fp = fopen("record.txt","ab+");  //fopen() function creates the file if it does not exist. --ab+ Open a binary file in append mode for writing at the end of the file.
            fflush(stdin);
                printf("\nStudent Name: ");gets(students.name);
                printf("\nStudent ID Number: ");scanf("%s",students.ID);
                printf("\nCourse: ");scanf("%s",students.course);
                printf("\nYear Level: ");scanf("%d",&students.yrlvl);
                printf("\nAge: ");scanf("%d",&students.age);

            FILE *fa;
            fa = fopen("record.txt","r");
            while(fread(&students,sizeof(students),1,fa) == 1) // 
            {
                if(strcmp(students.ID,students.ID) == 0) // Check if the user already in the file
                {
                    isFound = 1;
                    break;
                }
            }
            if(isFound == 1)
            {
                printf("\nStudent ID Number: %s already in the System. Please select Edit to modify same Student ID", students.ID);

            }
            else
            {
                fwrite(&students, sizeof(students), 1, fp); // Add Student 
printf("\nAdded Successfully");
            }
            fclose(fa);

                
            fclose(fp);// close the file

        return; 
    }

问题分析

  1. ID对比逻辑完全错误:strcmp(students.ID, students.ID)是将当前从文件读取的学生ID和自身比较,结果永远为0,导致第一次循环就标记isFound=1,无论输入ID是否重复。
  2. 输入数据被覆盖:读取文件时直接把数据写入students变量,覆盖了用户刚输入的信息,后续提示的ID是文件中读取的旧ID,而非用户输入的新ID。
  3. 文件操作冗余且不安全:同时打开两个文件指针操作同一文件,易引发指针位置混乱;gets()存在缓冲区溢出风险,fflush(stdin)属于未定义行为,不同编译器处理结果不一致。

修复后的代码

#include <string.h>
#include <stdio.h>

// 假设students是全局结构体,补充示例定义
typedef struct {
    char name[50];
    char ID[20];
    char course[50];
    int yrlvl;
    int age;
} Student;

Student students;

void add_student(){
    int isFound = 0;
    char inputID[20]; // 临时存储用户输入的ID,避免被覆盖
    FILE *fp;

    // 安全清理输入缓冲区
    int c;
    while ((c = getchar()) != '\n' && c != EOF);

    printf("\nStudent Name: ");
    fgets(students.name, sizeof(students.name), stdin);
    // 去除fgets读取的换行符
    students.name[strcspn(students.name, "\n")] = '\0';

    printf("\nStudent ID Number: ");
    scanf("%s", inputID);
    strcpy(students.ID, inputID); // 同步到结构体

    printf("\nCourse: ");
    scanf("%s", students.course);
    printf("\nYear Level: ");
    scanf("%d", &students.yrlvl);
    printf("\nAge: ");
    scanf("%d", &students.age);

    // 打开文件(可读可写)
    fp = fopen("record.txt", "rb+");
    if (fp == NULL) {
        // 文件不存在则创建
        fp = fopen("record.txt", "wb");
        if (fp == NULL) {
            printf("\nFailed to open file!");
            return;
        }
        fwrite(&students, sizeof(students), 1, fp);
        printf("\nAdded Successfully");
        fclose(fp);
        return;
    }

    // 遍历文件验证ID唯一性
    Student tempStudent;
    while (fread(&tempStudent, sizeof(tempStudent), 1, fp) == 1) {
        if (strcmp(tempStudent.ID, inputID) == 0) {
            isFound = 1;
            break;
        }
    }

    if (isFound == 1) {
        printf("\nStudent ID Number: %s already in the System. Please select Edit to modify same Student ID", inputID);
    } else {
        // 移动指针到文件末尾写入新数据
        fseek(fp, 0, SEEK_END);
        fwrite(&students, sizeof(students), 1, fp);
        printf("\nAdded Successfully");
    }

    fclose(fp);
    return;
}

关键修改点

  • 新增inputID临时变量存储用户输入的ID,避免读取文件时被覆盖
  • 修正ID对比逻辑:用文件中读取的tempStudent.ID和用户输入的inputID对比
  • 替换gets()为fgets()并处理换行符,消除缓冲区溢出风险
  • 用安全方式清理输入缓冲区,替代fflush(stdin)
  • 合并文件操作,使用单个文件指针完成验证与写入,避免指针混乱
  • 增加文件打开失败的异常处理

内容的提问来源于stack exchange,提问作者anna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 20:30:49