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

无法更新文本文件新数据,C语言文件更新代码故障求助

修复C语言文件数据更新功能失效问题

核心问题排查

  • 文件打开模式错误:用"a+"打开文件时,文件指针默认定位在末尾,fread根本读不到已有数据,直接导致找不到要更新的记录。必须用二进制读模式"rb"(或读写模式"rb+")来读取结构体数据。
  • 临时文件无错误检查:代码没判断temp文件是否创建成功,一旦创建失败后续操作会直接崩溃。
  • 字符串输入有溢出风险:scanf("%s", d.ad)这类写法没限制输入长度,若用户输入超过结构体字符数组的大小,会破坏内存。

修复后的完整代码

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

// 需确保结构体字符数组长度足够,示例定义如下
struct daire {
    int no;
    char ad[50];
    char soyad[50];
    float aidat;
    char tarih[20];
};

void bilgi_guncelle()
{
    struct daire d;
    FILE *dosya, *temp;
    int no, bulundu = 0;

    printf("Daire no: ");
    // 检查编号输入有效性
    if (scanf("%d", &no) != 1) {
        printf("Geçersiz numara girişi\n");
        return;
    }

    // 二进制模式打开目标文件,保证数据读取完整
    dosya = fopen("aidatlar.txt", "rb");
    if (dosya == NULL)
    {
        printf("Dosya açılmadı\n");
        return;
    }

    // 创建临时文件并检查是否成功
    temp = fopen("gecici.txt", "wb");
    if (temp == NULL) {
        printf("Geçici dosya oluşturulamadı\n");
        fclose(dosya);
        return;
    }

    while (fread(&d, sizeof(struct daire), 1, dosya) == 1)
    {
        if (d.no == no)
        {
            bulundu = 1;
            printf("Ad (%s): ", d.ad);
            // 限制输入长度,避免缓冲区溢出
            scanf("%49s", d.ad);

            printf("Soyad (%s): ", d.soyad);
            scanf("%49s", d.soyad);

            printf("Aidat (%.2f): ", d.aidat);
            // 检查费用输入有效性
            if (scanf("%f", &d.aidat) != 1) {
                printf("Geçersiz aidat girişi\n");
                d.aidat = 0.0f;
            }

            printf("Tarih (%s): ", d.tarih);
            scanf("%19s", d.tarih);
        }

        // 写入临时文件,同时检查写入是否成功
        if (fwrite(&d, sizeof(struct daire), 1, temp) != 1) {
            printf("Veri yazma hatası\n");
            fclose(dosya);
            fclose(temp);
            remove("gecici.txt");
            return;
        }
    }

    fclose(dosya);
    fclose(temp);

    if (!bulundu)
    {
        printf("Daire bulunamadı\n");
        remove("gecici.txt");
        return;
    }

    // 替换原文件前做错误检查,避免数据丢失
    if (remove("aidatlar.txt") != 0) {
        printf("Orijinal dosya silinemedi\n");
        remove("gecici.txt");
        return;
    }
    if (rename("gecici.txt", "aidatlar.txt") != 0) {
        printf("Dosya adı değiştirme hatası\n");
        printf("Güncellenmiş veri gecici.txt dosyasında bulunuyor\n");
        return;
    }

    printf("Bilgi başarıyla güncellendi\n");
}

关键优化说明

  • 用二进制模式读写结构体,避免文本模式下的换行符转换破坏数据结构。
  • 给scanf加长度限制,长度比数组小1,留位置给字符串终止符\0,彻底解决缓冲区溢出问题。
  • 增加了输入有效性和文件操作的错误处理,避免意外情况导致程序崩溃或数据丢失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 18:12:41