c - 无法从二进制文件中正确读取结构
问题描述
所以我的程序创建了一个二维动态结构数组,从二进制文件中读取这些结构,更改结构中的信息并将它们写入同一个文件中。问题是,它没有正确地从文件中读取信息。例如,我希望 info fromptr[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);
}
我想不出其他办法来解决这个问题。任何帮助将不胜感激。抱歉,代码量很大。
解决方案
在您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
呼叫。
推荐阅读
- authentication - 未调用默认身份验证策略
- pyautogui - 我目前正在尝试自动加入团队会议
- sql - 填充组中的列的值,该列在组中的同一列中具有空值和非空值
- python - 为什么 PIL.ImageGrab.grab() 并不总是返回相同大小的图像?
- c# - Azure IOT Hub SDK 使用布尔值设置设备孪生所需属性不起作用
- sql - presto sql中的笛卡尔积无限数量的组
- video - Bootsrap,视频上的文字
- angular - zxing-library 不读取条形码
- paypal - PayPal - IPN 历史页面 - 用户/查看权限设置
- kubernetes - 如何使用 virtualservice 来暴露 grafana prometheus 和 kiali 之类的仪表板?