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

C语言二进制文件项目调试出现breakpoint指令执行错误求助

解决C语言二进制文件写入员工信息时的调试断点错误

问题分析与修复步骤

以下是代码中导致断点错误的核心问题及对应修复方案:

1. 文件打开失败未处理

rb+模式要求目标文件已存在,若文件不存在fopen会返回NULL,后续对空指针的读写操作直接触发崩溃。需增加文件不存在时的创建逻辑:

FILE* f = fopen(numef, "rb+");
if (f == NULL) {
    // 文件不存在则创建并以读写模式打开
    f = fopen(numef, "wb+");
    if (f == NULL) {
        printf("无法打开或创建文件\n");
        return 1;
    }
}

2. 字符串输入的地址错误

scanf("%s", &numef);中numef是数组名,本身就是指向首元素的指针,无需取地址,修正为:

scanf("%s", numef);

3. 不安全函数与输入缓冲区残留问题

gets函数存在缓冲区溢出风险,改用fgets;同时scanf读取整数后残留的换行符会干扰后续输入,需提前清除:

// 替换原gets(a.nume)的逻辑
printf("Introduceti numele angajatului: ");
while (getchar() != '\n'); // 清除缓冲区剩余的换行符
fgets(a.nume, sizeof(a.nume), stdin);
a.nume[strcspn(a.nume, "\n")] = '\0'; // 移除fgets读取的换行符

4. double类型的格式符错误

salariu是double类型,scanf需用%lf格式符,而非%d,否则会破坏内存结构:

printf("Salariu: ");
scanf("%lf", &a.salariu);

5. feof(stdin)的错误用法

feof不能直接作为循环终止条件,应通过scanf的返回值判断是否成功读取数据:

printf("Introduceti ID angajat: ");
while (scanf("%d", &id) == 1) {
    // 原循环内部逻辑
    printf("Introduceti alt ID sau CTRL-Z+ENTER pt a iesi din fisier: ");
}

6. ftell返回值类型不匹配

ftell返回long型,用int存储可能导致溢出,修改articole函数的变量类型:

int articole(FILE* f, int lgart) {
    long pozp;
    long nrart;
    pozp = ftell(f);
    fseek(f, 0, SEEK_END); // 用SEEK_END代替2,提升可读性
    nrart = ftell(f) / lgart;
    fseek(f, pozp, SEEK_SET); // 用SEEK_SET代替0
    return (int)nrart;
}

修正后的完整代码

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

typedef struct {
    int id;
    int EsteSetat;
    char nume[100];
    int varsta;
    double salariu;
    char telefon[30];
} Angajat;

int articole(FILE* f, int lgart) {
    long pozp;
    long nrart;
    pozp = ftell(f);
    fseek(f, 0, SEEK_END);
    nrart = ftell(f) / lgart;
    fseek(f, pozp, SEEK_SET);
    return (int)nrart;
}

void scriere(FILE* f) {
    int id;
    Angajat a;
    printf("Introduceti ID angajat: ");
    while (scanf("%d", &id) == 1) {
        int nr_art = articole(f, sizeof(Angajat));
        if (id >= nr_art) {
            Angajat empty_a = {0}; // 初始化空结构体,避免随机值
            empty_a.EsteSetat = 0;
            fseek(f, 0, SEEK_END);
            for (int i = nr_art; i <= id; i++) {
                fwrite(&empty_a, sizeof(Angajat), 1, f);
            }
        }
        fseek(f, (long)id * sizeof(Angajat), SEEK_SET);
        fread(&a, sizeof(Angajat), 1, f);

        if (a.EsteSetat == 1) {
            printf("Angajatul deja exista\n");
        } else if (a.EsteSetat == 0) {
            a.EsteSetat = 1;
            a.id = id;
            printf("Introduceti numele angajatului: ");
            while (getchar() != '\n');
            fgets(a.nume, sizeof(a.nume), stdin);
            a.nume[strcspn(a.nume, "\n")] = '\0';

            printf("Varsta: ");
            scanf("%d", &a.varsta);

            printf("Salariu: ");
            scanf("%lf", &a.salariu);

            printf("Telefon: ");
            scanf("%s", a.telefon);

            fseek(f, (long)id * sizeof(Angajat), SEEK_SET);
            fwrite(&a, sizeof(Angajat), 1, f);
        }
        printf("Introduceti alt ID sau CTRL-Z+ENTER pt a iesi din fisier: ");
    }
}

int main() {
    char numef[20];
    printf("Introduceti numele fisierului: ");
    scanf("%s", numef);

    FILE* f = fopen(numef, "rb+");
    if (f == NULL) {
        f = fopen(numef, "wb+");
        if (f == NULL) {
            printf("Eroare la deschiderea fisierului\n");
            return 1;
        }
    }

    scriere(f);
    fclose(f);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 15:24:56