将char指针编写为文件问题的结构成员
我有一个struct成员作为char *并将其分配给结构初始化的字符串文字“John”,如下所示。 字符串打印精细与printf。
但是,如果我使用fwrite将此字符串写入文件,则在文件中我读回垃圾。
如果我使用char数组而不是char *(如图所示在结构中注释掉),并将其写入文件,我可以按预期读回文件中的字符串。 我无法理解这一点。 在两种情况下都不应该使用指针并将正确的字符串写入文件?
此外,如果我声明一个单独的char *并将其指向字符串文字并将其写入文件,我可以按预期读回。 非常感谢您提供任何解释方面的帮助。 (我在Windows上使用带有Mingw编译器的codeblocks IDE)。
更新:包括使用的实际代码
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); return 0; }
有了这个结构定义:
struct person { 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);
原因是变量p1
:的字节实际上不包含字符串“John”,但它包含指向字符串“John”的指针 ,该字符串是字符串“John”的内存地址。 现在fwrite(&p1, 1, 10, fp);
将从p1
的存储器地址开始写入10个字节,即(假设32位系统):4个字节表示指针,它只是一些存储器地址,4个字节表示1
(年龄),2个字节跟随在内存中不属于p1
变量。
现在,如果结构定义如下:
struct person { char name[20]; int age; };
情况完全不同。 这次变量p1
实际上包含字符串“John”。 前4个字节包含字符J
, o
, h
, n
然后是NUL字符,它是字符串终止符,然后跟随15个字节的未确定值。 然后按照表示age
4个字节。
在那种情况下, fwrite(&p1, 1, 10, fp);
将再次从p1
的存储器地址开始写入10个字节,但如上段所述,前4个字节包含“John”,第5个字节包含NUL终结符,其余5个字节具有不确定值。
评论者说,您提供的代码没有提供足够的信息来解决您的问题。 看起来错误在于代码中的其他位置。 我可以将您的代码转换为MCVE,如下所示:
#include 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; }
但我确信你所拥有的不同,因为这段代码有效:
John The stored name is: John
更新
从您提供的新代码中,我可以看到您的问题是您正在将struct
的内容写入文件而不是将字符串写入文件,就像在原始代码示例中一样。
使用的原始代码:
fwrite(p1.name, 1, 10, fp);
并将10个字节的字符串p1.name
写入文件"test.txt"
(吹过字符串"John"
的NUL
终结符并保存打印字符串时不会看到的垃圾值)。
新代码使用:
fwrite(&p1, 1, 10, fp);
将struct
p1
的前10个字节保存到文件"test.txt"
。
当struct
包含char name[20];
,前10个字节是字符数组name
存储的字符,这就是为什么你的代码在这种情况下似乎工作的原因。
当struct
改为包含char *name;
,保存的前几个字节属于指针name
(我系统上的8个字节),而不是字符串文字"John"
。 接下来的几个字节属于int
age
(我系统上的4个字节)。 这些值而不是在这种情况下保存的字符串文字"John"
的字符。
请注意,指针和int
的大小在不同的系统上可能不同,并且完全可以为指针提供4个字节,为int
4个字节,留下2个字节,这些字节不是struct
一部分。 此外,尽管这对您没有影响,但在struct
的第一个成员之后可能存在填充。