2201_76114441 2022-12-29 20:09 采纳率: 100%
浏览 26
已结题

为什么用fwrite写入账户时,就只能读出最后一个账户

用fwrite写入账户时,超过一个,就只能读出最后一个账户,完整代码如下

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




typedef struct BankAccount {
    int accountCard;//账户卡号
    char accountName[11];//储户名字,账户名称字符串后面的结束标记'/0'
    char mobile[12];//手机号码
    char cardId[19];//身份证
    char password[7];// 密码
    double money;//余额
} BA;
BA *bac;

int number;
void WriteData(BA *bac) {
    FILE *fp;
    if ((fp = fopen("account.txt", "w")) == NULL) {
        printf("\n\t打开文件失败!!\n");
        exit(0);
    }
    fwrite(&number, sizeof(int), 1, fp);
    //fseek(fp,sizeof(BA)*(number-1)*1l+sizeof(int),0);
    fwrite(bac, sizeof(BA), number, fp);

    fclose(fp);
}

void iniData(BA *bac) { //用于打开文件并初始化数据
    FILE *fp;
    int i;


    if ((fp = fopen("account.txt", "r")) == NULL) {
        printf("\n\t打开文件失败!!\n");
        exit(0);
    }

    fread(&number, sizeof(int), 1, fp);
    bac = (BA *)malloc(number * sizeof(BA));

    for (i = 0; i < number; i++) {
        fread(&(bac[i]), sizeof(BA), 1, fp);
        bankAccounts[i] = bac[i];
    }
    fclose(fp);
}

int main() {
    int y = 0; //用于选择需要服务
    int x = 0; //用于判断信息是否正确

    while (1) {
        printf("\n\t----------------------------------\n");
        printf("\n\t请选择需要的服务:               \n");
        printf("\n\t                                 \n");// ******************************
        printf("\n\t       1.储户新开户              \n");//********此处可以调用函数******
        printf("\n\t                                 \n");// ******************************
        printf("\n\t       0.退出                    \n");
        printf("\n\t----------------------------------\n");
        //控制输入的内容只能是'0'和'1'
        scanf("%d", &y);

        if (y == 1) {
            bac = (BA *)malloc((number + 1) * sizeof(BA));
        }
        if (y == 0) {
            WriteData(bac);
            free(bac);
            break;
        }

        //现在执行储户新开户
        while (1) {
            printf("\n\t请输入新的储户开户信息:\n");

            printf("\n\t姓名>>>");
            scanf("%s", &bac[number].accountName);



            printf("\n\t身份证号码 (18位)>>>");
            scanf("%s", &bac[number].cardId);



            printf("\n\t手机号码(11位)>>>");
            scanf("%s", &bac[number].mobile);



            printf("\n\t初始余额(100-20000)>>>");
            scanf("%lf", &bac[number].money);


            bac[number].accountCard = 80081 + number;

            //将输入的身份证后六位作为初始密码保存
            bac[number].password[0] = bac[number].cardId[1];
            bac[number].password[1] = bac[number].cardId[2];
            bac[number].password[2] = bac[number].cardId[3];
            bac[number].password[3] = bac[number].cardId[4];
            bac[number].password[4] = bac[number].cardId[5];
            bac[number].password[5] = bac[number].cardId[6];
            bac[number].password[6] = '\0';
            //将当前输入的验证合法的储户信息保存到新开户的储户信息

            //判断信息是否正确
            printf("\n\t储户姓名   身份证号码        手机号码       初始余额\n");
            printf("\t%s   %s   %s     %lf\n",
                   bac[number].accountName, bac[number].cardId, bac[number].mobile, bac[number].money);


            printf("\n\t若有错误,请按1,再按回车键;若正确,请按其它数字键,再按回车键!\n");
            scanf("%4d", &x);
            if (x == 1) {
                continue;
            } else {
                printf("\n\t您的卡号:%d\n", bac[number].accountCard);
                printf("\n\t您的初始密码:%s\n", bac[number].password);
                number++;
                break;
            }
        }
    }

    iniData(bac);
    printf("\n\t卡号 姓名      身份证       手机号码   密码   余额\n");
    for (int i = 0; i < number; i++) {
        printf("\n\t%d %s %s %s %s %.2lf\n",
               bankAccounts[i].accountCard,
               bankAccounts[i].accountName,
               bankAccounts[i].mobile,
               bankAccounts[i].cardId,
               bankAccounts[i].password,
               bankAccounts[i].money);
    }
}

  • 写回答

1条回答 默认 最新

  • ShowMeAI 2022-12-29 20:40
    关注

    在这段代码中,我们使用了文件打开模式为 "w" 的 fopen 函数来打开文件,这意味着如果文件存在,它将被覆盖;如果文件不存在,则会新建一个文件。


    因此,在调用 WriteData 函数之前,如果我们想将多个账户写入文件中,就需要先将所有账户信息存储到一个数组中,然后再将整个数组写入文件。


    为了解决这个问题,我们可以在 iniData 函数中将所有账户信息读入内存,然后将这些信息保存到一个数组中,最后再将数组传递给 WriteData 函数。下面是修改后的代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct BankAccount {
        int accountCard;//账户卡号
        char accountName[11];//储户名字,账户名称字符串后面的结束标记'/0'
        char mobile[12];//手机号码
        char cardId[19];//身份证
        char password[7];// 密码
        double money;//余额
    } BA;
    
    int number;
    
    void WriteData(BA *bac) {
        FILE *fp;
        if ((fp = fopen("account.txt", "w")) == NULL) {
            printf("\n\t打开文件失败!!\n");
            exit(0);
        }
        fwrite(&number, sizeof(int), 1, fp);
        fwrite(bac, sizeof(BA), number, fp);
    
        fclose(fp);
    }
    
    void iniData(BA **bac) { //用于打开文件并初始化数据
        FILE *fp;
        int i;
    
        if ((fp = fopen("account.txt", "r")) == NULL) {
            printf("\n\t打开文件失败!!\n");
            exit(0);
        }
    
        fread(&number, sizeof(int), 1, fp);
        *bac = (BA *)malloc(number * sizeof(BA));
    
        for (i = 0; i < number; i++) {
            fread(&((*bac)[i]), sizeof(BA), 1, fp);
        }
        fclose(fp);
    }
    
    int main() {
        int y = 0; //用于选择需要服务
        int x = 0; //用于判断信息是否正确
    
        BA *bac;
        iniData(&bac);
    
        while (1) {
            printf("\n\t----------------------------------\n");
            printf("\n\t请选择需要的服务:               \n");
            printf("\n\t                                 \n");// ******************************
            printf("\n\t       1.储户新开户              \n");//********此处可以调用函数******
            printf("\n\t                                 \n");// ******************************
            printf("\n\t       0.退出                    \n");
            printf("\n\t----------------------------------\n");
            //控制输入的内容只能是'0'和'1'
            scanf("%d", &y);
    
            if (y == 1) {
                bac = (BA *)realloc(bac, (number + 1) * sizeof(BA));
            }
            if (y == 0) {
                WriteData(bac);
                free(bac);
                break;
            }
    
            //现在执行储户新开户
            while (1) {
                printf("\n\t请输入新的储户开户信息:\n");
    
                printf("\n\t卡号:");
                scanf("%d", &bac[number].accountCard);
                getchar();
    
                printf("\n\t储户名字:");
                gets(bac[number].accountName);
    
                printf("\n\t身份证:");
                gets(bac[number].cardId);
    
                printf("\n\t手机号码:");
                gets(bac[number].mobile);
    
                printf("\n\t密码:");
                gets(bac[number].password);
    
                printf("\n\t余额:");
                scanf("%lf", &bac[number].money);
                number++;
                break;
            }
        }
        return 0;
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 1月6日
  • 已采纳回答 12月29日
  • 创建了问题 12月29日

悬赏问题

  • ¥15 vscode的问题提问
  • ¥50 切换TabTip键盘的输入法
  • ¥15 可否在不同线程中调用封装数据库操作的类
  • ¥15 微带串馈天线阵列每个阵元宽度计算
  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 Centos / PETGEM