I'm practising how to work with binary files and playing around with storing, reading and printing out some int values. So, naturally, I've come across a little something that does not affect the functionality of the code (that is, for what I want it to do so far) but it bugs me because I can't seem to find an answer as to why it happens.
I've found, as you'll see in the code below, that if I assign 'cod.x' as a parameter in the function 'create' (right as it is right now), then assign 'cod.y' to the fread in the 'read' function BUT instead I set it to print 'cod.x' in the following line, I end up getting a sequence of 9s. Which makes perfect sense, it was the last int value assigned by the for loop in the former function.
Now, however, if in both functions I swap 'cod.x' for 'cod.y' (that's to say, I order it to print 'cod.y' expecting to see the sequence of 9s again) I get 0s, as I would (correctly, I think, since it's been unused so far) with 'cod.z'.
If in this second go I used 'cod.y' only back in the fuction 'create', why does this happen? Shouldn't the 9s carry through like it did with 'cod.x' before?
What am I missing?
(Funny thing is I found the 9s do carry through if I assign 'cod.z' (instead of 'cod.x') to the fread in the 'read' function. Then, in the next line, I order it to print 'cod.y' and the sequence of 9s is there all right!
So, it sort of seems like a new function writing new data on a variable that 'comes before' the one used by the preceding function ( x is declared "before" y , y "before" z...in a way?) automatically deletes what the the latter variable had stored. I don't know if this is at all a relevant observation but I did point it out.)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct nums{
int x, y, z;
}cod;
void create(FILE* BinList);
void read(FILE* BinList);
//void change(FILE* BinList);
int main(void)
{
FILE * BinList;
BinList = fopen("handylist.bin", "wb");
if (!BinList) return 1;
create(BinList); //sequence 0123456789 is written in the bin file
BinList = fopen("handylist.bin", "rb");
if (!BinList) return 1;
read(BinList); // sequence is printed in both ascending and descending order
return 0;
}
void create(FILE* BinList) {
int i;
for (i = 0; i < 10; i++)
{
cod.x = i;
fwrite(&cod.x, sizeof(struct nums), 1, BinList);
}
printf("Last stored value: %d", cod.x);
fclose(BinList);
}
void read(FILE* BinList)
{
int i;
printf("\n\nCopied Data:");
for (i = 0; i < 10; i++)
{
fread(&cod.y, sizeof(struct nums), 1, BinList);
printf("\n%d", cod.y); //here is where the problem happens
}
printf("\n\n\n");
printf("Values: x:%d, y:%d, z:%d\n",cod.x,cod.y,cod.z); //checking struct values
printf("Order is inverted:\n");
for (i = 9; i >= 0; i--)
{
fseek(BinList, sizeof(struct nums) *i, SEEK_SET);
fread(&cod.z, sizeof(struct nums), 1, BinList);
printf("%d \n", cod.z);
}
fclose(BinList);
}
As to your reply to my hint, I'll provide more details here as a answer.
fwrite(&cod.x, sizeof(struct nums), 1, BinList);
Here you write from the address of x
in the structure cod
a number of bytes. You write the whole struct. There is no problem because &cod
and &cod.x
are the same because x
is the first member of the structure.
fread(&cod.y, sizeof(struct nums), 1, BinList);
Here you read a number of bytes. You read the size of the whole strucure, that is you read an x, y and z. But you place that starting at cod.y
. So you put there bytes for the value of y, of z and of ??? There is no more structure to place bytes! So the last bytes you place "in memory that is not yours."
cod.x y z ???
+----+----+----+----....
| | | |
+----+----+----+----....
^ ^ ^
| | |
----+----+----+ read puts the data here