问题
I have a struct member as a char * and assign it to a string literal "John" on the struct initialisation as shown below. The string prints fine with printf.
However, if I write this string to a file using fwrite, in the file I read back garbage.
If I use a char array instead of a char * (commented out in the struct as shown), and write it to the file, I can read back the string in the file as expected. I can't understand this. Shouldn't fwrite in both cases take the pointer and write the correct string to the file?
Furthermore , if I declare a separate char * and point it to a string literal and write it to the file, I can read it back as expected. Many thanks in advance for any help with explanation. (I am using codeblocks IDE with Mingw compiler on Windows).
UPDATED : To include actual code used
int main()
{
struct person
{
//char name[20];
char* name;
int age;
};
struct person p1 = {"John", 25};
printf("%s\n", p1.name);
FILE* fp = fopen("test.txt", "w");
fwrite(&p1, 1, 10, fp);
fclose(fp);
return 0;
}
回答1:
With this structure definition:
struct person
{
char* name;
int age;
};
following code won't do what you expect:
struct person p1 = {"John", 25};
printf("%s\n", p1.name);
FILE* fp = fopen("test.txt", "w");
fwrite(&p1, 1, 10, fp);
The reason is that bytes of the variable p1
: doesn't actually contain the string "John", but it contains a pointer to the string "John", that is a the memory address of the string "John". Now fwrite(&p1, 1, 10, fp);
will write 10 bytes starting from the memory address of p1
, that is (assuming a 32 bit system): 4 bytes representing the pointer which is just some memory address, 4 bytes representing 1
(age) and 2 bytes that follow in memory that don't belong to the p1
variable.
Now if the structure is define like this:
struct person
{
char name[20];
int age;
};
The situation is entirely different. This time the variable p1
actually does contain the string "John". the first 4 bytes contain the characters J
, o
, h
, n
then follows a NUL character which is the string terminator and then follow 15 bytes of undetermined value. Then follow 4 bytes representing age
.
In that case the fwrite(&p1, 1, 10, fp);
will again write 10 bytes starting from the memory address of p1
, but as explained in the paragraph above, the first 4 bytes contain "John", the 5th byte contains the NUL terminator and the 5 remaining bytes are of indeterminate value.
回答2:
The commenters are saying that the code you provided does not give enough information to solve your problem. It looks like the error lies elsewhere in your code. I can convert your code to a MCVE like this:
#include <stdio.h>
struct person
{
//char name[20];
char* name;
int age;
};
int main(void)
{
struct person p1 = {"John", 25};
printf("%s\n", p1.name);
FILE *fp = fopen("test.txt", "w");
fwrite(p1.name, 1, 10, fp);
fclose(fp);
char buffer[20];
fp = fopen("test.txt", "r");
fread(buffer, 1, 10, fp);
fclose(fp);
printf("The stored name is: %s\n", buffer);
return 0;
}
But I am sure that what you have differs, because this code works:
John
The stored name is: John
Update
From the new code that you provided, I can see that your problem is that you are writing the contents of a struct
to a file instead of writing a string to a file, as in your original code example.
The original code used:
fwrite(p1.name, 1, 10, fp);
and wrote 10 bytes of the string p1.name
to the file "test.txt"
(blowing right past the NUL
terminator of the string "John"
and saving garbage values that would not be seen on printing the string).
The new code uses:
fwrite(&p1, 1, 10, fp);
saving the first 10 bytes of the struct
p1
to the file "test.txt"
.
When the struct
contains char name[20];
, the first 10 bytes are char
s stored in the character array name
, and this is why your code appeared to work in this case.
When the struct
instead contains char *name;
, the first few bytes saved belong to the pointer name
(8 bytes on my system), not to the string literal "John"
. The next few bytes belong to the int
age
(4 bytes on my system). It is these values and not the char
s of the string literal "John"
that are being saved in this case.
Note that the sizes of pointers and int
s may be different on different systems, and it is entirely possible to have 4 bytes for the pointer and 4 bytes for the int
, leaving 2 bytes which are saved that are not part of the struct
. Also, though this does not affect you here, there may be padding after the first member of the struct
.
来源:https://stackoverflow.com/questions/41042480/writing-char-pointer-as-struct-member-to-file-issue