酒店管理计划中的神秘错误 - C.

时间:2013-10-01 10:30:05

标签: c loops fwrite fread

我制定了酒店管理计划。它有一个问题:在Accounts函数中,它应该通过程序重置已注册成员的所有标志。但是它有一个错误。我花了很多个月,试图调试这个问题,但我不能。所以请帮助我。这是帐户功能的代码,

void accounts()
{
    int ttt=0;
    struct person payment;
    char aname[21], oname[21];
    char *namea;
    int chec=1, ver=0;
    long int recsize;
    recsize=sizeof(payment);
    f=fopen("C:\\HOTEL.DAT", "rb+");
    if(f == NULL){
        clrscr();
        cprintf("File could not be opened!");
        sleep(4);
        exit(0);
    }
    clrscr();
    cprintf("\n                   *** Pearl Guest House - Payments ***\n\n");
    cprintf("\r\r\rEnter the Name :");
    fflush(stdin);
    scanf("%[^\n]s", &aname);
    namea=strupr(aname);
    strcpy(oname, namea);
    while(fread(&payment, recsize, 1, f) == 1){

        if((payment.flag == 1) && (strcmp(payment.name,oname) == 0)){
            payment.pay=1;
            printf("\n\n Payment Received");
            fflush(stdin);
            getch();
            ver=1;

            fseek(f, -recsize, SEEK_CUR);
            fwrite(&payment, sizeof(payment), 1, f);
            break;

        }

    }

    if(ver!=1){
        printf("\n\n Record not Found!!!");
        fflush(stdin);
        getch();
    }
    //rewind(f);
    fclose(f);
    f=fopen("C:\\HOTEL.DAT", "rb+");
    if(f == NULL){
        clrscr();
        cprintf("File could not be opened!");
        sleep(4);
        exit(0);
    }

    while(fread(&payment, recsize, 1, f) == 1){
        if(payment.pay==0){
            chec=0;
            break;
        }
    }
    //rewind(f);
    f=fopen("C:\\HOTEL.DAT", "rb+");
    if(f == NULL){
        clrscr();
        cprintf("File could not be opened!");
        sleep(4);
        exit(0);
    }

    if(chec==1){
            while(fread(&payment, recsize, 1, f) == 1){
                payment.pay=0;
                fseek(f, -recsize, SEEK_CUR);
                fwrite(&payment, recsize, 1, f);
                ttt++;
                printf("%d", ttt);
            }

            printf("\n\n All payments recieved...\n\nSo, the payments flags are set to 0");
            fflush(stdin);
            getch();
    }
    printf("Before Fclose");
    fclose(f);
    printf("After Fclose");
}

这是我的结构人:

struct s_office{   
    char name[16];
    char phone[12];
    };
struct permanent{
    char addr[100];
    char phone[12];
    };

struct emergency{
    char name[21];
    char relation[11];
    char phone[12];
};

struct person{
    char name[21];
    char phone[12];
    char place[21];
    int roomno;
    int flag;
    char food;
    struct s_office office;
    char father[21];
    char fphone[12];
    struct permanent per;
    struct emergency emer1;
    char email[40];
    int finger;
    char dob[8];
    int cidate;
    int cimonth;
    int ciyear;
    int codate;
    int comonth;
    int coyear;
    int rent;
    int pay;
};

以下是我收录的标题列表:

#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
#include<dos.h>

我使用Turbo C ++编写此代码。 当它运行时,它成功运行但输出不是应该的。 (它应该打开文件(在哪里是商店数据 - HOTEL.DAT),逐个读取所有书面函数,然后如果它看到所有这些函数都有薪酬变量= 1;它应该说“收到所有付款。 ..“然后它应该将它们全部设置为0)  我试图调试并发现最可能的错误在于:

while(fread(&payment, recsize, 1, f) == 1){
                payment.pay=0;
                fseek(f, -recsize, SEEK_CUR);
                fwrite(&payment, recsize, 1, f);
                ttt++;
                printf("%d", ttt);
            }

这里我认为循环是好的,因为如果我评论循环的内容,它运行n次。 (如果n =条目数)但是如果我取消注释它没有的内容!这就是问题。因此,它不会将它们全部设置为0。 我想要的是这个问题和代码的解决方案,以便它提供所需的输出(将每个薪酬变量设置为0)

记住:这是一个14岁的小孩试图编码;请礼貌和详细地帮助和回答;;;致谢

我已将代码移至Visual Studio Express 2012,现在它显示了一个更多的问题 它进入帐户的无限循环并创建数千个条目! 这是代码

void accounts()
{
    int ttt=0;
    struct person payment;
    char aname[21], oname[21];
    char *namea;
    int chec=1, ver=0;
    long int recsize;
    recsize=sizeof(payment);
    f=fopen("D:\\HOTEL.DAT", "rb+");
    if(f == NULL){
        system("cls");
        cprintf("File could not be opened!");
        MySleep(4);
        exit(0);
    }
    system("cls");
    cprintf("\n                   *** Pearl Guest House - Payments ***\n\n");
    cprintf("\r\r\rEnter the Name :");
    fflush(stdin);
    scanf("%[^\n]s", &aname);
    namea=strupr(aname);
    strcpy(oname, namea);
    while(fread(&payment, recsize, 1, f) == 1){

        if((payment.flag == 1) && (strcmp(payment.name,oname) == 0)){
            payment.pay=1;
            printf("\n\n Payment Received");
            fflush(stdin);
            getch();
            ver=1;

            fseek(f, -recsize, SEEK_CUR);
            fwrite(&payment, sizeof(payment), 1, f);
            break;

        }

    }

    if(ver!=1){
        printf("\n\n Record not Found!!!");
        fflush(stdin);
        getch();
    }
    //rewind(f);
    fclose(f);
    f=fopen("D:\\HOTEL.DAT", "rb+");
    if(f == NULL){
        system("cls");
        cprintf("File could not be opened!");
        MySleep(4);
        exit(0);
    }

    while(fread(&payment, recsize, 1, f) == 1){
        if(payment.pay==0){
            chec=0;
            break;
        }
    }
    //rewind(f);
    f=fopen("D:\\HOTEL.DAT", "rb+");
    if(f == NULL){
        system("cls");
        cprintf("File could not be opened!");
        MySleep(4);
        exit(0);
    }

    if(chec==1){
            while(fread(&payment, recsize, 1, f) == 1){
                payment.pay=0;
                fseek(f, -recsize, SEEK_CUR);
                fwrite(&payment, recsize, 1, f);
                ttt++;
                printf("%d", ttt);
            }

            printf("\n\n All payments recieved...\n\nSo, the payments flags are set to 0");
            fflush(stdin);
            getch();
    }
    printf("Before Fclose");
    fclose(f);
    printf("After Fclose");
}

1 个答案:

答案 0 :(得分:2)

您是否在调试器中运行此代码以查看是否可以确定错误?没有这样做,我们都在黑暗中刺伤......

无论如何,你有两个我可以看到的问题。

  • 这段代码不会一致地运作:
    
    while(fread(&payment, recsize, 1, f) == 1){
                payment.pay=0;
                fseek(f, -recsize, SEEK_CUR);
                fwrite(&payment, recsize, 1, f);
                ttt++;
                printf("%d", ttt);
            }

在评论中说明的chux,您应该在fflush(f)之后致电fwritefwritefflush都可以并且将返回错误,您不会检查错误或处理错误。这也可能是你腐败的根源。

  • 结构包装(如评论中Jongware所述)

结构包装意味着几件事:

  • 结构中字段之间的填充量
  • 添加到结构末端以使其在自然边界上结束的填充量。大多数32位机器都喜欢它们的数据以32位边界开始。

某些机器不能使用未对齐的字段并且需要一些hackery,例如,这意味着32位int应该从32位对齐边界开始并以32位对齐边界结束。我可以想到至少有一个处理器使用页面错误来处理这种情况,从而大大减慢了代码的速度。页面错误比直接内存读取和写入慢一个数量级,因此结构打包变得非常重要。

在Intel x86处理器上,未对齐的读/写写入的代价不是很高,因此关闭结构封装会有些安全。查看#pragma pack的Turbo C ++文档。这将引导您阅读所需的知识以解决问题。一旦理解了编译器文档,就去搜索互联网并阅读有关结构填充/打包的信息。

确保每个结构只有一个定义。

我觉得我忘了什么,但是......希望这会让你开始。