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

C语言转账功能异常排查:疑似空格字符导致的文件写入问题

C语言转账功能故障排查:空格与文件读写问题

问题描述

注册功能可正常将客户信息写入test.txt文件,但转账(havale)功能无法正常执行。该功能逻辑为读取文件内容、完成转账操作后重新写入文件,怀疑是空格字符引发的问题,需排查具体原因及解决方法。

核心原因分析

  1. 文件写入时的换行错误
    转账函数重写文件时,错误地将换行符输出到控制台(printf("\n")),而非写入文件。这会导致所有客户记录在文件中挤成一行,后续fgets读取时无法正确拆分每条记录,进而导致IBAN匹配失败、转账逻辑失效。

  2. IBAN验证函数的越界风险
    ibankontrol函数中循环条件为i < 27,但struct müşteri的iban数组长度为27(含字符串终止符'\0'),有效IBAN字符最多26位。循环到i=26时会访问数组的终止符位置,可能引发非法内存访问或验证逻辑错误。

  3. 不必要的fflush(stdin)调用
    fflush对标准输入流的行为是C标准未定义的,不仅无意义,还可能导致跨平台兼容性问题。

解决方法

  1. 修正文件写入的换行逻辑
    将转账函数中输出换行的printf("\n")替换为fprintf(dosya, "\n"),确保每条客户记录在文件中单独占一行。

  2. 调整IBAN验证的循环边界
    将ibankontrol中的循环条件改为i < 26,避免访问数组的终止符位置。

  3. 移除无效的fflush(stdin)
    删除所有fflush(stdin)调用,scanf("%s")会自动跳过输入中的空白字符,无需额外处理。

修正后的完整代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>   
#define I 27
#define DosyaAdi "test.txt"

struct  müşteri
{
    char iban[I];
    long long tc;
    int bakiye;
};

int ibankontrol(char iban[])
{
    if(!isalpha(iban[0]) || !isalpha(iban[1]))
        return 0;
    // 修正循环边界,避免访问终止符
    for (int i = 2; i < 26; i++)
    {
        if (iban[i]<48 || iban[i]>57)
        {
            return 0;
        }
    }
    return 1;
}

int tckontrol(long long tc)
{
    int a=0,bas;
    long long i=1;
    while (a<11)
    {
        bas=(tc/i)%10;
        if (bas<0 || bas>9)
        {
            return 0;
        }
        
        i*=10;
        a++;
    }
    if (tc / i > 0) {
        return 0;
    }
    return 1;
}

int kaydet(struct müşteri m)
{
    FILE *dosya;
    dosya=fopen(DosyaAdi,"a");
    if (dosya==NULL)
    {
        printf("\nKayıt başarısız\n");
        return 0;
    }
    
    fprintf(dosya,"%lld %d %s\n",m.tc,m.bakiye,m.iban);

    fclose(dosya);
    return 1;
}

int havale(char kaynak[],char hedef[],int miktar)
{
    struct müşteri müşteriler[100];
    int i=0,y=0,z=0;
    char string[100];
    FILE *dosya;
    dosya=fopen(DosyaAdi,"r");
    if (dosya == NULL) { // 新增文件打开失败判断
        printf("Dosya okunamadı.\n");
        return 0;
    }
    while (1)
    {
        if ((fgets(string,100,dosya))==NULL)
        {
            break;
        }
        sscanf(string,"%lld %d %s",&müşteriler[i].tc,&müşteriler[i].bakiye,müşteriler[i].iban);
        i++;
    }   

    for(z=0;z<i;z++)
    {
        printf("\nGuncel bilgiler:\n");
        printf("%d: %s  %lld  %d\n",z+1,müşteriler[z].iban,müşteriler[z].tc,müşteriler[z].bakiye);
    }

    fclose(dosya);
    for (int j = 0; j < i; j++)
    {
        if (strcmp(kaynak,müşteriler[j].iban) == 0)
        {
            müşteriler[j].bakiye -= miktar;
            y++;
        }
        if (strcmp(hedef,müşteriler[j].iban) == 0)
        {
            müşteriler[j].bakiye += miktar;
            y++;
        }
    }

    if (y != 2)
    {
        printf("Kaynak veya hedef IBAN bulunamadı.\n");
        return 0;
    }
    
    dosya = fopen(DosyaAdi, "w");
    if (dosya == NULL)
    {
        printf("Dosya açılamadı.\n");
        return 0;
    }
    
    for (int s = 0; s < i; s++)
    {
        fprintf(dosya, "%lld %d %s", müşteriler[s].tc, müşteriler[s].bakiye, müşteriler[s].iban);
        if (s!=i-1)
        {
            // 修正:将换行写入文件而非控制台
            fprintf(dosya, "\n");
        }
        
    }
    fclose(dosya);
    
    printf("Havale başarılı!\n");
    return 1;
}


int main()
{
    int seçim;
    int dönüş=0,kontrol=0;
    char kaynak[27],hedef[27];
    int miktar=0;
    struct müşteri m;

    while (1)
    {
        printf("Menü:\n");
        printf("1:Kayıt\n");
        printf("2:Havale\n");
        printf("3:Çıkış\n");
        printf("Seçiminiz: ");
        scanf("%d",&seçim);

        switch (seçim)
        {
        case 1:
       
            while (1)
            {
                printf("İban giriniz: ");
                scanf("%s",m.iban);
                // 移除fflush(stdin)
                dönüş=ibankontrol(m.iban);
                if (dönüş==0)
                {
                    printf("İban yanlış!\n");
                }
                else if (dönüş==1)
                {
                    break;
                }
            }
            while (1)
            {
                printf("TC giriniz: ");
                scanf("%lld",&m.tc);
                // 移除fflush(stdin)
                dönüş=tckontrol(m.tc);
                if (dönüş==0)
                {
                    printf("TC yanlış!\n");
                }
                else if (dönüş==1)
                {
                    break;
                }
            }
            
            printf("Bakiye giriniz: ");
            scanf("%d",&m.bakiye);

            kontrol=kaydet(m);
            if (kontrol==0)
            {
                printf("Kayıt başarısız!\n");
            }
            else if (kontrol==1)
            {
                printf("Kayıt başarılı!\n");
                break;
            }
            break;
        case 2:
            printf("Kaynak iban: ");
            scanf("%s",kaynak);
             
            // 移除fflush(stdin)
            
            printf("Hedef iban: ");
            scanf("%s",hedef);
   
            // 移除fflush(stdin)

            printf("Gönderilicek miktar: ");
            scanf("%d",&miktar);

            int a=havale(kaynak,hedef,miktar);
            if (a==0)
            {
                printf("Havale başarısız\n");
            }
            break;
        case 3:
            exit(EXIT_SUCCESS); // 替换为标准退出码
            break;
        default:
            printf("Geçersiz işlem!\n");
            break;
        }
    }
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 17:07:02