fread/fwrite string in C
Solution 1
I see two problems with the write, you are setting record.nameLength to be too small, and you are passing the wrong pointer to fwrite for the name. record.name is already a pointer.
Change this
record.nameLength = strlen(name)-1;
...
fwrite(&record.name,sizeof(char),record.nameLength,fp);
to this
record.nameLength = strlen(name);
...
fwrite(record.name,sizeof(char),record.nameLength,fp);
You also have a problem on the read, since you aren't writing the terminating \0 from the strings into your file, when you read back, you need to add that terminator explicitly.
char *nameString = malloc(sizeof(char)* (record.nameLength + 1));
fread(nameString,sizeof(char),record.nameLength,fp);
nameString[record.NameLength] = '\0';
Solution 2
The problem is that you pass the pointer to the char*
in your fwrite:
fwrite(&record.name,sizeof(char),record.nameLength,fp);
This means that instead of writing the name, you're writing the memory address of the name. Fwrite
expects a pointer to the data to write—in your case, that's the pointer to the char
data, not the pointer to the pointer of the char
data.
Pass it record.name
instead of &record.name
and you should be set:
fwrite(record.name, sizeof(char), record.nameLength, fp);
Related videos on Youtube
Comments
-
Blackbinary over 4 years
I have a binary file which contains records. The structure of the file is as such:
Structure (see below) Name String Address String
The structure in question:
typedef struct{ char * name; char * address; short addressLength, nameLength; int phoneNumber; }employeeRecord; employeeRecord record;
I get the name as such:
char name[50]; printf("\nName:"); fgets(name,50,stdin); record.nameLength = strlen(name)-1; record.name = malloc(sizeof(char)*record.nameLength); strcpy(record.name,name);
I write the structure, the the name, then the address (as mentioned above).
fwrite(&record.name,sizeof(char),record.nameLength,fp);
where fp is a file pointer.
Now i close the file. However, if i then want to read from the file to get this data back, I believe I need to read in the structure, read the nameLength variable, malloc enough memory for the name to sit in, then fread the name into the variable.
Like so:
char *nameString = malloc(sizeof(char)*record.nameLength); fread(nameString,sizeof(char),record.nameLength,fp); printf("\nName: %s",nameString);
However, when i attempt this, i do not get valid data. Example:
Input name is: Joseph (6 characters) Output data: Name length is 6 (correct), Name is �A � (aka garbage)
So obviously im doing something wrong. Could someone give me some help?
-
zneak over 14 yearsIt won't solve anything, but you could use
strdup
instead ofstrlen
+malloc
+strcpy
. -
John Zwinck over 14 yearsIs this a homework assignment?
-
Blackbinary over 14 yearsadded homework tag, forgot about that.
-
-
Blackbinary over 14 yearswhy do i need the null terminator? I know the size of what I'll be reading, so don't i just want to chop it off anyways?
-
Blackbinary over 14 yearsalso, if i use the name 'M' for example, using
record.nameLength=strlen(name)
returns a length of 2, not 1. -
John Knoeller over 14 yearsstrlen doesn't include the null terminator in it's length. (unless you wrote your own strlen function?), strlen("M") will return 1, not 2.
-
mctylr over 14 yearsC strings end with a NULL character ('\0') so that the string related functions, including printf, know when the string ends, because C strings unlike Pascal strings, don't keep an internal string length, so the string "goes on" until it finds a '\0' character to terminate it. This is a common source of problems for new C programmers.