c语⾔中将结构体写⼊⽂件,C语⾔中将结构体写⼊⽂件
可以使⽤fwrite()将⼀个结构体写⼊⽂件:
fwrite(&some_struct,sizeof somestruct,1,fp);
对应的fread函数可以再把它读出来,此处fwrite受到⼀个结构的指针并把这个结构的内存映像作为字节流写⼊⽂件。sizeof操作符计算出结构占⽤的字节数。
但是这样⽤内存映像写出的数据⽂件却是不能够移植的,尤其是当结构中包含浮点成员或指针的时候。结构的内存布局跟机器和编译器都有关。不同的编译器可能使⽤不同数量的填充位,不同机器上基本类型的⼤⼩和字节顺序也不尽相同。因此,作为内存映像写出的结构在别的机器上(甚⾄是被别的编译器编译之后)不⼀定能被读回来。
同时注意如果结构包含任何指针(char*字符串或指向其他数据结构的指针),则只有指针值会被写⼊⽂件。当它们再次被读回来的时候可能已经失效。最后为了⼴泛的可移植性,你必需⽤“b”标志打开⽂件。
读写结构体的程序如下:
将结构体写⼊⽂件:
#include
#includec语言中struct
typedef
struct {
char c;
int h;
short n;
long m;
float f;
double d1;
char *s;
double d2;
}st;
int main(
void)
{
FILE *fp;
st sa,sb;
char *str=
"
abcdefg
";
sa.c=
'
K
';
sa.h=-
3;
sa.n=
20;
sa.m= 100000000; sa.f=
33.32f;
sa.d1=
78.572;
sa.d2=
33.637;
sa.s=str;
fp=fopen(
"
<
",
"
w+
");
if(!fp)
{
printf(
"
errror!\n ");
exit(-
1);
}
printf(
"
sa:c=%c,h=%d,n=%d,m=%d,f=%f,d1=%f,s=%s,d2=%f\n
",sa.c,sa.h,sa.n,sa.m,sa.f,sa.d1,sa.s,sa.d2);
printf(
"
sizeof(sa)=%d:&c=%x,&h=%x,&n=%x,&m=%x,&f=%x,&d1=%x,&s=%x,&d2=%x\n ",
sizeof(sa),&sa.c,&sa.h,&sa.n,&sa.m,&sa.f,&sa.d1,&sa.s,&sa.d2);
fwrite(&sa,
sizeof(sa),
1,fp);
rewind(fp);
fread(&sb,
sizeof(sb),
1,fp);
printf(
"
sb:c=%c,h=%d,n=%d,m=%d,f=%f,d1=%f,s=%s,d2=%f\n
",sb.c,sb.h,sb.n,sb.m,sb.f,sb.d1,sb.s,sb.d2);
fclose(fp);
return
0;
}
从⽂件中读出结构体:
#include
#include
typedef
struct {
char c;
int h;
short n;
float f;
double d1;
char *s;
double d2;
}st;
int main(
void)
{
FILE *fp;
st sb;
fp=fopen(
"
<
",
"
r
");
if(!fp)
{
printf(
"
errror!\n
");
exit(-
1);
}
fread(&sb,
sizeof(sb),
1,fp);
printf(
"
sb:c=%c,h=%d,n=%d,m=%d,f=%f,d1=%f,s=%s,d2=%f\n ",sb.c,sb.h,sb.n,sb.m,sb.f,sb.d1,sb.s,sb.d2);
"
sizeof(sb)=%d:&c=%x,&h=%x,&n=%x,&m=%x,&f=%x,&d1=%x,&s=%x,&d2=%x\n
",
sizeof(sb),&sb.c,&sb.h,&sb.n,&sb.m,&sb.f,&sb.d1,&sb.s,&sb.d2);
fclose(fp);
return
0;
}
在linux平台下的GCC编译器进⾏编译后的结果如下:
⾸先是结构体写⼊⽂件:
sa:c=K,h=-3,n=20,m=100000000,f=33.320000,d1=78.572000,s=abcdefg,d2=33.637000
sizeof(sa)=40:&c=bfb98a10,&h=bfb98a14,&n=bfb98a18,&m=bfb98a1c,&f=bfb98a20,&d1=bfb98a24,&s=bfb98a2c,&d2=b
sb:c=K,h=-3,n=20,m=100000000,f=33.320000,d1=78.572000,s=abcdefg,d2=33.637000
从⽂件中读出结构体:
sb:c=K,h=-3,n=20,m=100000000,f=33.320000,d1=78.572000,s=���o��,d2=33.637000
sizeof(sb)=40:&c=bfbc9964,&h=bfbc9968,&n=bfbc996c,&m=bfbc9970,&f=bfbc9974,&d1=bfbc9978,&s=bfbc9980,&d2=b
在windows xp 平台下利⽤Visual C++编译器编译后结果如下:
写⼊结构体:
sa:c=K,h=-3,n=20,m=100000000,f=33.320000,d1=78.572000,s=abcdefg,d2=33.637000
sizeof(sa)=48:&c=12ff28,&h=12ff2c,&n=12ff30,&m=12ff34,&f=12ff38,&d1=12ff40,&s=12ff48,&d2=12ff50
sb:c=K,h=-3,n=20,m=100000000,f=33.320000,d1=78.572000,s=abcdefg,d2=33.637000
读出结构体:
sb:c=K,h=-3,n=20,m=100000000,f=33.320000,d1=78.572000,s=e,d2=33.637000
sizeof(sb)=48:&c=12ff28,&h=12ff2c,&n=12ff30,&m=12ff34,&f=12ff38,&d1=12ff40,&s=12
从上⾯的结果我们可以得到如下⼏个结论:
1. 如果结构体中含有指针,是很容易出问题的,从上⾯的结果中(⾼亮)部分可以看到字符串的输出结果是不⼀样的,这说明,在进⾏写⼊⽂
件的时候,char*所指向的字符串没有写⼊⽂件,只是将指针写⼊,当从⽂件中读出结构体,再次得到这个指针的时候,由于程序运⾏的内
存位置变化,所以原来指针所指向的内容也变了,所以输出也变了。
2. 还有⼀个⽐较重要的是结构体的内存对其问题(之前也讨论过)。可以看到,不同的编译器采取的⽅式是不⼀样的。 gcc中的结构体⼤⼩为
40字节,⽽VC下是48个字节。
并且GCC下,结构体内存的起始位置是4的倍数,⽽VC中是8的倍数。这是因为,结构体的起始地址与其中所包含的拥有最多字节的类型有关。之前也说过,因为GCC的处理⽅式是如果结构体内有超过4个字节的类型,那么结构体起始位置以4的倍数开始, ⽽VC中是以最⼤字
节数的为准。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论