【问题标题】:Unable to read from a .dat file in C无法从 C 中的 .dat 文件中读取
【发布时间】:2018-08-01 00:56:24
【问题描述】:

我创建了一个程序,它从用户那里获取帐户信息并将其存储到文件 accounts.dat 中。由于程序现在是这样,在我关闭它并重新打开以对其进行测试之前,它似乎一切正常,它不会读取我已经输入的任何信息。案例 6 是它应该从 accounts.dat 中读取的位置。 accounts.dat 似乎确实填满了信息,每次我使用它时。

/* HEADER FILES */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* STRUCT TO HOLD ACCOUNT INFO */
struct bank
{
    char first[25];
    char middle[25];
    char last[25];
    long int aNumber;
    float aBalance;
};

/* MAIN START*/
int main()
{
    int choice; /* SWITCH-STATEMENT CASE */
    int i; /* FOR-LOOP COUNTER */
    int  count; /* KEEPS TRACK OF TOTAL # OF ACCOUNTS */
    long int aNumber; /* TEMPORARILY HOLDS ACCOUNT # FOR SEARCH IN FILE */
    float amount; /* TEMPORARILY HOLDS A DOLLAR AMOUNT FOR VARIOUS REASONS */
    FILE *fp; /* SPECIFIC FILE DECLARATION FOR OUR BANK */
    struct bank account[50]; /* ARRAY DECLARATION FOR STRUCT */

    /* DO/WHILE START */
    do
    {
        /* OPTION MENU */
        printf("\n\nWelcome to yor bank access.\n"
               "Please follow the prompts below.\n\n"
               "\t0. Exit\n"
               "\t1. Deposit\n"
               "\t2. Withdrawal\n"
               "\t3. Add account\n"
               "\t4. Remove Account\n"
               "\t5. Balance Inquiry\n"
               "\t6. View Account\n"
               "\nEnter your choice: ");
        scanf("%d",&choice);
        printf("\n");

        /* SWITCH START */
        switch(choice)
        {

        /* CASE 0: EXIT PROGRAM */
        case 0:
            exit(1);
            break;

        /* CASE 1: DEPOSIT */
        case 1:
            fopen("accounts.dat", "r+");
            fseek(fp,0,SEEK_SET);
            printf("please enter account number: ");
            scanf("%ld",&aNumber);
            printf("Amount to be deposited: $");
            scanf("%f", &amount);
            for(i=0; i<count; i++)
            {
                if(account[i].aNumber == aNumber)
                {
                    account[i].aBalance = account[i].aBalance + amount;
                    fseek(fp,i * sizeof(struct bank),SEEK_SET);
                    fwrite(account+i,sizeof(struct bank),1, fp);
                    break;
                }
            }
            if(i==count)
                printf("Account number does not exits\n");
            break;

        /* CASE:2 WITHDRAWAL */
        case 2:
            fopen("accounts.dat", "r+");
            fseek(fp,0,SEEK_SET);
            printf("Please enter account number: ");
            scanf("%ld",&aNumber);
            printf("Enter the amount to be withdrawn: $");
            scanf("%f",&amount);
            for(i=0; i<count; i++)
            {
                if(account[i].aNumber==aNumber)
                {
                    if(account[i].aBalance<amount)
                    {
                        printf("Insufficient balance\n");
                        break;
                    }
                    account[i].aBalance=account[i].aBalance-amount;
                    fseek(fp,i*sizeof(struct bank),SEEK_SET);
                    fwrite(account+i,sizeof(struct bank),1, fp);
                    break;
                }
            }
            if(i==count)
                printf("Account number does not exits\n");
            break;

        /* CASE 3: ADD ACCOUNT */
        case 3:
            fp = fopen("accounts.dat","a+");
            printf("Enter a 6-digit account number: ");
            scanf("%ld",&aNumber);
            for(i=0; i<count; i++)
            {
                if(account[i].aNumber==aNumber)
                {
                    printf("Account already exist\n");
                    break;
                }
            }
            if(i==count)
            {
                account[i].aNumber=aNumber;

                printf("Enter the First Name: ");
                scanf("%s",account[i].first);

                printf("Enter the Middle Initial: ");
                scanf("%s",account[i].middle);

                printf("Enter the Last Name: ");
                scanf("%s",account[i].last);

                printf("Enter the Amount: $");
                scanf("%f",&account[i].aBalance);
                fseek(fp,0,SEEK_END);
                fwrite(account+i,sizeof(struct bank),1, fp);
                count++;
            }
            break;

        /* CASE 4: DELETE ACCOUNT */
        case 4:
            fopen("accounts.dat", "a+");
            fseek(fp,0,SEEK_SET);
            printf("Please enter account number: ");
            scanf("%ld",&aNumber);
            for(i=0; i<count; i++)
            {
                if(account[i].aNumber==aNumber)
                    break;
            }
            if(i==count)
                printf("Account number does not exits\n");
            else
            {
                while(i<count)
                {
                    strcpy(account[i].first,account[i+1].first);
                    strcpy(account[i].middle,account[i+1].middle);
                    strcpy(account[i].last,account[i+1].last);
                    account[i].aNumber=account[i+1].aNumber;
                    account[i].aBalance=account[i+1].aBalance;
                }
                count--;
                fp=fopen("accounts.dat", "wb");
                for(i=0; i<count; i++)
                    fwrite(account+i,sizeof(struct bank),1, fp);
                fclose(fp);
                /* REOPEN FILE */
                fopen("accounts.dat", "r+");
            }
            break;

        /* CASE 5: BALANCE INQUIRY*/
        case 5:
            fopen("accounts.dat", "r");
            printf("Please enter account number: ");
            scanf("%ld",&aNumber);
            for(i=0; i<count; i++)
            {
                if(account[i].aNumber==aNumber)
                {
                    printf("First Name: %s\n",account[i].first);
                    printf("Middle Initial: %s\n",account[i].middle);
                    printf("Last Name: %s\n",account[i].last);
                    printf("Account Number: %ld\n",account[i].aNumber);
                    printf("Balance Amount: $%.2f\n",account[i].aBalance);
                    break;
                }
            }
            if(i==count)
                printf("Account number does not exits\n");
            break;

        /* CASE 6: VIEW ACCOUNTS*/
        case 6:
            fopen("accounts.dat", "r");
            for(i=0; i<count; i++)
            {
                fread(&account[i], sizeof(account), 1, fp);
                printf("Entry %1d\n", i+1);
                printf("First Name: %s\n",account[i].first);
                printf("Middle Initial: %s\n",account[i].middle);
                printf("Last Name: %s\n",account[i].last);
                printf("Account Number: %ld\n",account[i].aNumber);
                printf("Account Balance: $%.2f\n",account[i].aBalance);
            }
        } /* END SWITCH-STATEMENT */
    } /* END 'DO' */
    while(choice!=0);
    return 0;
}

【问题讨论】:

  • 您必须在每个 scanf验证返回,例如scanf("%s",account[i].first);(或该点的任何输入函数)以确保您实际处理的是有效数据。检查退货。
  • 这与minimal reproducible example 相差甚远。阅读How to Ask

标签: c file-handling


【解决方案1】:

当您以案例 6 启动程序时,count 未初始化,导致 for 循环出现意外行为。

【讨论】:

  • 不仅仅是案例 6。i &lt; count 测试在 6 个不同的位置使用,但 count 从未在整个代码中的单个位置初始化。
【解决方案2】:

正如已经指出的那样,count 尚未初始化,但通常会在您退出程序并稍后重新启动时以零值开始。虽然这不能保证,但如果它为零,您会发现循环将提前终止。

因此,在重新启动时,您需要做的是读回 dat 文件中的记录数并将计数初始化为该数字,然后一切都应该从那里开始。您可能想要创建一个新选项“读取现有文件”或类似的选项来进行扫描。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多