0

我做了一个酒店管理程序。有个问题是:Accounts功能中,要通过程序重置所有注册会员的flag。但是有一个错误,它没有。我花了很多个月,试图调试这个问题,但我做不到。所以请帮助我。这是帐户功能的代码,

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

1 回答 1

2

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

无论如何,我可以看到您有 2 个可能的问题。

  • 这段代码将无法始终如一地工作:
    
    while(fread(&payment, recsize, 1, f) == 1){
                付款.pay=0;
                fseek(f, -recsize, SEEK_CUR);
                fwrite(&payment, 调整大小, 1, f);
                ttt++;
                printf("%d", ttt);
            }

在评论中所述的 chux 处,您应该fflush(f)fwrite. fwrite并且fflush两者都可以并且将返回错误并且您没有检查错误或处理它们。这也可能是你腐败的根源。

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

结构包装意味着几件事:

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

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

在 Intel x86 处理器上,未对齐的读/写的惩罚不是很高,因此关闭结构打包在一定程度上是安全的。查看#pragma pack 的 Turbo C++ 文档。这将引导您阅读您需要做的阅读以理解该问题。一旦你理解了编译器文档,去搜索互联网并阅读结构填充/打包。

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

我觉得我忘记了一些东西,但是.... 希望这会让你开始。

于 2013-10-01T14:42:05.957 回答