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

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

#include 
#include 
#include 




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);
    }
}

在这段代码中,我们使用了文件打开模式为 "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;
}