Reputation: 357
My Function That writes to the file:
Record_t * load_Record(FILE * infile)
{
Record_t *r;
char title[TITLE_SIZE];
char [MEDIUM_SIZE];
int ID, rating;
if ((fscanf(infile,"%d: %s %d", &ID, medium, &rating) != 3 && fgets(title, TITLE_SIZE, infile))){
return NULL;
}
printf("medium is: %s title is: %s\n", medium, title);
r = create_Record(medium, title);
set_Record_rating(r, rating);
return r;
}
where Record_t is defined as:
typedef struct Record {
int ID;
char * title;
char * medium;
int rating;
} Record_t;
My main:
#include "Record.h"
#include <stdlib.h>
int main()
{
char * title = "The Queen";
char * medium = "DVD";
FILE * pfile ;
struct Record *t = create_Record(medium, title); //creates a record
struct Record *s;
set_Record_rating (t, 3);
print_Record(t);
pfile = fopen("output.txt", "w");
save_Record(t, pfile);
fclose(pfile);
destroy_Record(t); //de-allocates memory
pfile = fopen("output.txt", "r");
if(!(s = load_Record(pfile))){
return 1;
}
print_Record(s);
fclose(pfile);
destroy_Record(s);
return 0;
}
output.txt after being written to file:
1: DVD 3 The Queen //checked for excess whitespace(has newline however)
Terminal output:
1: The Queen DVD 3
medium is: DVD title is: � //title being saved inappropriately
@
2: �
@ DVD 3
now my fgets function is wrong! For some reason, the title is being saved inappropriately
i am compiling with the following flags: gcc -ansi -std=c89 -pedantic -Wmissing-prototypes -Wall test.c Record.c -o test
where test.c is my main
Upvotes: 1
Views: 853
Reputation: 8255
You've not allocated a buffer for medium:
char * medium;
That just creates a pointer to a char called medium, you've not reserved any memory space to read into. This would allocate 256 bytes (allowing you to read up to 256 characters) for medium:
medium = malloc(256);
Or you can allocate on the stack:
char medium[256];
Given the issues you're having, I would suggest using allocation on the stack, then just read and write the struct to the file — it saves you from having to parse the fields yourself etc. at expense of disk space (you could be writing out a lot of blank characters) but this wastage would be negligible in this scenario.
fwrite(t, sizeof(Record_t), 1, pFile);
fread(t, sizeof(Record_t), 1, pFile);
Upvotes: 2
Reputation: 75150
char * medium;
This should be
char medium[SOME_CONSTANT]; // or char* medium = malloc(x); if you need the
// memory to persist after the function returns
So that you actually have medium
pointing to some memory you own. As it is now, your pointer is pointing to garbage and you're expecting fscanf
to save a string in the memory it points to.
If a function ever appears to return a pointer to some magically created memory, you better check the documentation twice (unless that function happens to be the stupid strdup
). The function either actually expects a pointer to some already-allocated memory, or returns a pointer that points to a block of memory allocated with someone from malloc
's family, in which case you need to take responsibility for deallocating it.
Only in very rare circumstances do functions return a pointer to memory without taking a preallocated buffer in and without having malloc
d it (especially when the string that is returned is of unpredictable size like it is for fscanf
).
Upvotes: 4
Reputation: 755064
Several ways:
You've not allocated the space for it to read the string into. You need:
char medium[100];
You don't check for errors properly:
if (!(fscanf(infile,"%d: %s %d", &ID, medium, &rating)
should be:
if (fscanf(infile,"%d: %s %d", &ID, medium, &rating) != 3 ...
You need to explicitly test that you got all the values you expected to read.
That's scratching the surface without a deep analysis of all the code. Note that you'll need to be sure that you are not trying to return medium
to the calling code. This should be OK if create_record()
does a reasonable job. It is odd that create_record()
isn't told the record ID.
Upvotes: 1