Reputation: 513
I´m trying to save and read struct
s from a binary file and I'm having problems. The thing is that it seems that it is being saved properly. Nevertheless, when reading it, it either shows weird characters or throw a "segmentation fault" error.
This is my struct:
typedef struct
{
char* P;
char* R1;
char* R2;
char* R3;
} t_p_r;
These are the methods I am using for reading and writing them:
Method for saving/reading singular structures:
void saveSing(t_p_r P)
{
FILE* f = fopen("PR.dat", "wb");
fputc(1, fichero);
fwrite(&P, sizeof(t_p_r), 1, f);
fclose(f);
}
void ReadSing(t_p_r* P)
{
FILE* f = fopen("PR.dat", "rb");
fread(P, sizeof(t_p_r) , 1, f);
fclose(f);
}
Methods I have tried to save arrays of t_p_r
void SaveR(t_p_r P[], int num)
{
FILE* f= fopen("PR.dat", "wb");
fputc(num, f);
fwrite(&P, sizeof( t_p_r), num, f);
fclose(f);
}
int ReadR(t_p_r* P)
{
int numElem;
FILE* f= fopen("PR.dat", "rb");
numElem = fgetc(f);
P= (t_p_r*) malloc((numElem) * sizeof(t_p_r));
fread(&P, sizeof(t_p_r) , numElem, f);
fclose(f);
return numElem;
}
In the case of the first set of methods, I have the problem of getting rare symbols (not the ones entered in the char*
that are being saved. In the second one, instead, I get A segmentation fault when trying to read them.
Upvotes: 0
Views: 99
Reputation: 44284
When saving the state of a program to file, it never makes sense to save the value of pointers. The value of a pointer is never consistent from program invocation to program invocation.
What you must do is to save the actual data values. In many cases it is not enough to just save data values. You may also need some kind of meta-data to explain what is coming next. Examples of meta-data is "type" (i.e. are the next bytes a int32 or int16 or a string) and "number of bytes" (i.e. how many bytes does the next variable occupy). This is often referred to as serialization.
You can find libs that have such functionality for almost any kind of data type.
If you want to write it yourself, you need to figure out what you want to write to the file and how you'll identify the fields when you read it back.
Let us say that all you want is to save objects of your rype t_p_r
. The first questions to answer is "what are those char pointers pointing to" and "how will you identify the values when reading a file".
Let us say they point to C type strings. Then your approach could be to save each variable on a new line. That is - each t_p_r
will take 4 lines in the file.
So in pseudo code your write function would be:
for each t_p_r variable:
write to file the string that P points and a newline
write to file the string that R1 points and a newline
write to file the string that R2 points and a newline
write to file the string that R3 points and a newline
The reading is a bit more complicated:
while not end of file:
allocate memory for a t_p_r variable
read a line from the file
t_p_r->P = allocate memory to hold the line
strcpy(t_p_r->P, line)
read a line from the file
t_p_r->R1 = allocate memory to hold the line
strcpy(t_p_r->R1, line)
read a line from the file
t_p_r->R2 = allocate memory to hold the line
strcpy(t_p_r->R2, line)
read a line from the file
t_p_r->R3 = allocate memory to hold the line
strcpy(t_p_r->R3, line)
Upvotes: 2
Reputation: 298
You need to write the actual strings to the file
fputc(strlen(P->P), f); fwrite(P->P, strlen(P->P), 1, f);
fputc(strlen(P->R1), f); fwrite(P->R1, strlen(P->R1), 1, f);
fputc(strlen(P->R2), f); fwrite(P->R2, strlen(P->R2), 1, f);
fputc(strlen(P->R3), f); fwrite(P->R3, strlen(P->R3), 1, f);
There might be better ways to deal with it, but I couldn't comment without more of your code.
Upvotes: 1