可以使用fwrite()将一个结构体写入文件:

fwrite(&some_struct,sizeof somestruct,1,fp);

对应的fread函数可以再把它读出来,此处fwrite受到一个结构的指针并把这个结构的内存映像作为字节流写入文件。sizeof操作符计算出结构占用的字节数。

但是这样用内存映像写出的数据文件却是不能够移植的,尤其是当结构中包含浮点成员或指针的时候。结构的内存布局跟机器和编译器都有关。不同的编译器可能使用不同数量的填充位,不同机器上基本类型的大小和字节顺序也不尽相同。因此,作为内存映像写出的结构在别的机器上(甚至是被别的编译器编译之后)不一定能被读回来。

同时注意如果结构包含任何指针(char*字符串或指向其他数据结构的指针),则只有指针值会被写入文件。当它们再次被读回来的时候可能已经失效。最后为了广泛的可移植性,你必需用“b”标志打开文件。

读写结构体的程序如下:

将结构体写入文件:

#include

#include

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(

"

st.txt

",

"

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;

long m;

float f;

double d1;

char *s;

double d2;

}st;

int main(

void)

{

FILE *fp;

st sb;

fp=fopen(

"

st.txt

",

"

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);

printf(

"

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=bfb98a30

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=bfbc9984

在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中是以最大字节数的为准。

ps:4的倍数就是地址的最低两位是00,8的倍数就是地址最低三位为000

然后我分别在linux下读入winxp写的结构体文件和在winxp下读入linux下写的结构体文件,两个平台下的程序都崩溃了。

c语言中将结构体写入文件,C语言中将结构体写入文件相关推荐

  1. C语言文件缓冲区作用,C语言 文件操作4--文件结构体FILE的理解以及缓冲区再讲...

    //文件结构体FILE的理解以及缓冲区再讲 #include #include //要点:文件结构 //struct _iobuf { // char *_ptr; ------当前缓冲区内容指针 / ...

  2. C语言之简单版本银行储蓄系统4(结构体版本)

    1.老学长的唠叨 在上一个编的数组版本的简化银行系统的基础上改为结构体存储,为还没有学到结构体的学弟学妹们提供一个迁就的方案,现在将程序改为结构体存储了,也希望学弟学妹们有个c语言学习缓冲的时间,这个 ...

  3. c语言字节写入文件,C语言文件操作

    所谓文件(file)一般指存储在外部介质上数据的集合,比如我们经常使用的mp3.mp4.txt.bmp.jpg.exe.rmvb等等.这些文件各有各的用途,我们通常将它们存放在磁盘或者可移动盘等介质中 ...

  4. c语言结构体和联合体,C语言结构体和联合体

    1.单链表插入 #include #include #define FALSE 0 #define TRUE 1 typedef struct NODE{ STRUCT NODE *link; int ...

  5. 遍历结构体_三菱ST语言编程(3)——结构体变量

    上篇文章介绍了数组,是一组相同类型数据的列表,那么不同类型的数据能否组合到一起用一个标签表示呢?答案当然是可以的,而实现这个功能的就是结构体(struct). 建立结构体 在三菱结构化编程的界面中左侧 ...

  6. c语言中申请内存并初始化,c语言中结构体的定义、初始化及内存分配

    #include struct person { char *name; int age; }; int main() { //结构体可以定义在函数内,也可以定义到函数外 //相当于全局变量与局部变量 ...

  7. 结构体复数相乘c语言,复数乘法中的结构体赋值实现代码

    复数乘法中的结构体赋值实现代码 废话不多说,直接上代码 复制代码 代码如下: #include using namespace std; typedef struct { double real; d ...

  8. c语言用数组直接填充结构体,C语言第11题:结构体数组的定义与使用 + 结构体数组排序...

    C语言第11题:结构体数组的定义与使用 + 结构体数组排序 C语言第11题:结构体数组的定义与使用 + 结构体数组排序 注意: 一下赋值是不能使用的 但是在结构体中是可以直接进行赋值操作的 st[1] ...

  9. c语言中结构体类型定义的函数指针,结构体中定义函数指针

    结构体指针变量的定义 定义结构体变量的一般形式如下:形式1:先定义结构体类型,再定义变量struct 结构体标识符{ 成员变量列表;-};struct 结构体标识符 *指针变量名;变量初始化:stru ...

最新文章

  1. Apache 与Tomcat
  2. 富士康裁员六万,试图用机器人扭转赤字?
  3. [转]Python UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 的解决办法...
  4. 推荐一本书《网络机器人java编程指南》
  5. u-boot.lds 文件分析
  6. 一个小技巧助您减少if语句的状态判断
  7. Silverlight Gantt甘特图项目管理解决方案
  8. hql mysql查询语句,HQL查询语言的使用介绍
  9. MAC下MySQL启动不了怎么办?
  10. 无效的wechatwin.dll文件errcode:126,点击“确定”下载最新版本
  11. 识别中文_中文场景文字识别大赛官方baseline
  12. httpd linux启动脚本,Linux下一个智能重启Apache服务器的脚本分享
  13. QQ for linux
  14. 用iSSH代替Mobile Terminal管理iOS
  15. 十大经典算法及其优化
  16. IE 11中 onpropertychange失效
  17. PLL锁相环及其locked信号
  18. 摘果子问题(聚沙成塔问题)
  19. 信道容量受哪三个要素_连续信道容量与
  20. 2022年最新浙江道路运输安全员真题题库及答案

热门文章

  1. 纯C++操作文件和文件夹的工具类
  2. thinkphp实现简易签到
  3. 创业失败经历、创业能力与后续创业企业成长绩效关系研究
  4. 【调剂】北京交通大学在职专业学位中心2023年硕士研究生复试录取工作办法
  5. Unity 协程探究
  6. C语言中getopt()函数的用法
  7. linux(ubuntu)无法连接网络
  8. C++ 图片格式转化和压缩
  9. Android build.gradle 配置
  10. 攻防世界 REVERSE 新手区/maze