So my program creates an 2d-dynamic array of structures, reads these structures from a binary file, changes the information in the structures and writes them in the same file. The problem is, that it does not read the information from the file properly. For example, I expect the info from ptr[0][0].Flat_ID
to be 101. But on the console it prints a random number, say10948144
, and this jeopardizes my entire program. I tried to change the way it reads, but to no effect.
Here is my 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;
}
My header file:
#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
And my source file:
#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);
}
I can think of no other way to fix this. Any help would be appretiated. Sorry for the huge amount of code.
In your memalloc
and these lines you close the file
fread(&floors,sizeof(unsigned),1,f);
fread(&flats_per_floor,sizeof(unsigned),1,f);
fclose(f);
but later in your loop you try to read from it, and a few lines after this you close it again
for(int j = 0; j < flats_per_floor; j++)
{
fread(&Apartment,sizeof(S_Apartament),1,f);
arr[i][j]=Apartment;
}
Try removing the first fclose
call.