无法从二进制中正确读取结构

问题描述 投票:0回答:1

因此,我的程序创建了一个二维动态结构数组,从二进制文件中读取这些结构,改变结构中的信息,并将它们写入同一个文件。问题是,它不能正确地从文件中读取信息。例如,我希望从以下文件中读取信息 ptr[0][0].Flat_ID是101。但在控制台上,它打印了一个随机的数字,比如说10948144这将危及我的整个程序。我试图改变它的阅读方式,但没有效果。main():

#include "Header.h"

int main()
{
    while(1)
    {
        printf("Hello world!\n");
        unsigned int floors=0, flats_per_floor=0;
        S_Apartament Flats;
        char FileName[50];
        printf("0. Exit program.\n");
        printf("1. Enter a file name.\n");
        printf("Please, choose a command.\n");
        unsigned short choice;
        scanf("%hu", &choice);
        if(choice == 0)
        {
           break;
        }
        else
        {
            printf("Enter file name in the following format 'Name.bin' :");
            scanf("%s", FileName);
        }
        S_Apartament **ptr = memalloc(floors, flats_per_floor, Flats, FileName);
        printf("%u",ptr[0][0].Flat_ID);
        while(1)
        {
            choice = menu();
        if(choice==0)
        {
            break;
        }
        switch(choice)
        {
            case 1:
                enterNewResidents(ptr, floors, flats_per_floor);
                break;
            case 2:
                calculateTax(ptr, floors, flats_per_floor);
                break;
            case 3:
                Elevator(ptr, floors, flats_per_floor);
                break;
            case 4:
                emptyApartment(ptr, floors, flats_per_floor);
                break;
            default:
                printf("Invalid command\n");
                break;
        }
        writeInfo(ptr,floors,flats_per_floor, FileName);
        free(ptr);
        }
    }
    printf("Program exited successfully. Have a nice day");
    return 0;
}

我的头文件。

#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
   unsigned int Flat_ID;
   unsigned short count_Rooms;
   unsigned short count_Adults;
   unsigned short count_Children;
   char Family_Surname[20];
   char Date[10];
   float rent;
}S_Apartament;
unsigned short menu();
S_Apartament** memalloc(unsigned int floors, unsigned int flats_per_floor, S_Apartament Apartment, char FileName[50]);
void enterNewResidents(S_Apartament **ptr, unsigned floors, unsigned flats_per_floor);
void calculateTax(S_Apartament **ptr, unsigned floors, unsigned flats_per_floor);
void emptyApartment(S_Apartament **ptr, unsigned floors, unsigned flats_per_floor);
void Elevator(S_Apartament **ptr, unsigned floors, unsigned flats_per_floor);
void writeInfo(S_Apartament **ptr, unsigned floors, unsigned flats_per_floor, char FileName[50]);

#endif // HEADER_H_INCLUDED

还有我的源文件

#include "Header.h"

unsigned short menu()
{
    unsigned short choice=0;
    printf("Welcome, to the smart House manager program! Here is a list of the available commands.\n");
    printf("1. Enter new residents.\n");
    printf("2. Calculate month tax.\n");
    printf("3. Set elevator\n");
    printf("4. Empty an apartment\n");
    printf("0. Exit the program\n");
    printf("Please choose a command:\n");
    scanf("%hu",&choice);
    return choice;
}
S_Apartament** memalloc(unsigned int floors, unsigned int flats_per_floor, S_Apartament Apartment, char FileName[50])
{
    FILE *f;
        f = fopen(FileName,"rb");
        if(f==NULL)
        {
            printf("Error opening file, or no such file.");
            fclose(f);
            exit(1);
        }
        fread(&floors,sizeof(unsigned),1,f);
        fread(&flats_per_floor,sizeof(unsigned),1,f);
        fclose(f);
        S_Apartament **arr = (S_Apartament **)malloc(sizeof(S_Apartament*) * floors);
        for (int i = 0; i <  floors; i++)
        {
            arr[i] = (S_Apartament *)malloc(sizeof(S_Apartament)*flats_per_floor);
            printf("Here");
        }
        for(int i = 0; i <  floors; i++)
        {
            for(int j = 0; j < flats_per_floor; j++)
            {

                fread(&Apartment,sizeof(S_Apartament),1,f);
                arr[i][j]=Apartment;
            }
        }
        fclose(f);
        return arr;
}
void enterNewResidents(S_Apartament **ptr, unsigned floors, unsigned flats_per_floor)
{
    unsigned short a = 0, b = 0;
    printf("Enter the floor, where you wish to accommodate the new residents.\n");
    scanf("%hu", &a);
    printf("Good, now the flat.\n");
    scanf("%hu", &b);
    if((a > floors) || (b > flats_per_floor))
    {
        printf("Invalid coordinates.");
    }
    if(ptr[a-1][b-1].count_Adults==0)
    {
        printf("The apartment is free to use. Enter the following data:\n");
        printf("Enter the number of adults\n");
        scanf("%hu", &(ptr[a-1][b-1].count_Adults));
        printf("Enter the number of children\n");
        scanf("%hu", &(ptr[a-1][b-1].count_Children));
        printf("Enter the name of the Family\n");
        scanf("%s", ptr[a-1][b-1].Family_Surname);
        printf("Date of entry:\n");
        scanf("%s", ptr[a-1][b-1].Date);
        printf("Enter the rent\n");
        scanf("%f", &(ptr[a-1][b-1].rent));
    }
    else
    {
       printf("The apartment is occupied. Please, choose another one.\n");
    }

}
void calculateTax(S_Apartament **ptr, unsigned floors, unsigned flats_per_floor)
{
    int Tax = 0;
    for(int i=0; i<floors; i++)
    {
        for(int j=0; i<flats_per_floor; j++)
        {
            if( (i==0) || (i==1) )
            {
                Tax = Tax + (3*ptr[i][j].count_Adults) + (1*ptr[i][j].count_Children);
            }
            else
            {
                Tax = Tax + (5*ptr[i][j].count_Adults) + (3*ptr[i][j].count_Children);
            }
        }
    }
    printf("Tax is: %d \n", Tax);
}
void Elevator(S_Apartament **ptr, unsigned floors, unsigned flats_per_floor)
{
    unsigned short Elevator_location = 1;
    unsigned number_of_residents = 0;
    unsigned max_amount = 0;
    for(int i = 1; i < floors - 1; i++)
    {
        for(int j = 0; j<flats_per_floor; j++)
        {
            number_of_residents = number_of_residents + ptr[i][j].count_Adults + ptr[i][j].count_Children + ptr[i-1][j].count_Adults + ptr[i-1][j].count_Children + ptr[i+1][j].count_Adults + ptr[i+1][j].count_Children;
        }
        if(number_of_residents >= max_amount)
        {
            max_amount = number_of_residents;
            number_of_residents = 0;
            Elevator_location = i + 1;
        }
        else
        {
            number_of_residents = 0;
        }
    }
    printf("The elevator's default floor is to be set to ");
    if(Elevator_location == 2)
    {
        printf("%hu nd floor.\n", Elevator_location);
    }
    else if(Elevator_location == 3)
    {
        printf("%hu rd floor.\n", Elevator_location);
    }
    else
    {
        printf("%hu th floor.\n", Elevator_location);
    }
}
void emptyApartment(S_Apartament **ptr, unsigned floors, unsigned flats_per_floor)
{
    unsigned short Entered_number = 0;
    int i = 0, j = 0;
    printf("Enter the number of the apartment you wish to empty:\n");
    scanf("%hu", &Entered_number);
    for(i=0; i<floors; i++)
    {
        for(j=0; j<flats_per_floor; j++)
        {
            if(Entered_number == ptr[i][j].Flat_ID)
            {
               ptr[i][j].count_Adults = 0;
               ptr[i][j].count_Children = 0;
               ptr[i][j].Family_Surname[0] = '\0';
               ptr[i][j].rent = 0.00;
               printf("Apartment is empty");
               break;
            }
        }
        if(Entered_number == ptr[i][j].Flat_ID)
        {
            printf("TEST");
            break;
        }
        else if(i == (floors - 1))
        {
            printf("No such apartment");
        }
    }
}
void writeInfo(S_Apartament **ptr, unsigned floors, unsigned flats_per_floor, char FileName[50])
{
    FILE *fp;
    fp = fopen(FileName,"wb");
    if(fp==NULL)
    {
        printf("Error opening file");
        fclose(fp);
        exit(2);
    }
    fwrite(&floors,sizeof(unsigned),1,fp);
    fwrite(&flats_per_floor,sizeof(unsigned),1,fp);
    for(int i = 0; i <  floors; i++)
            {
                for(int j = 0; j < flats_per_floor; j++)
                {
                    fwrite(&ptr[i][j],sizeof(S_Apartament),1,fp);
                }
            }
    fclose(fp);
}

我想不出其他办法来解决这个问题。任何帮助都将是感激的。对不起,代码量太大了。

c io structure binaryfiles dynamic-memory-allocation
1个回答
1
投票

在你的 memalloc 和这些行你关闭文件

 fread(&floors,sizeof(unsigned),1,f);
 fread(&flats_per_floor,sizeof(unsigned),1,f);
 fclose(f);

但在你的循环中,你试图从它那里读取,而在这之后的几行中,你又关闭了它。

for(int j = 0; j < flats_per_floor; j++)
{
   fread(&Apartment,sizeof(S_Apartament),1,f);
   arr[i][j]=Apartment;
}

试着去掉第一个 fclose 呼叫。

© www.soinside.com 2019 - 2024. All rights reserved.