可以使用fwrite()将一个结构体写入文件:
  fwrite(&some_struct,sizeof somestruct,1,fp);
对应的fread函数可以再把它读出来,此处fwrite受到一个结构的指针并把这个结构的内存映像作为字节流写入文件。sizeof操作符计算出结构占用的字节数。
但是这样用内存映像写出的数据文件却是不能够移植的,尤其是当结构中包含浮点成员或指针的时候。结构的内存布局跟机器和编译器都有关。不同的编译器可能使用不同数量的填充位,不同机器上基本类型的大小和字节顺序也不尽相同。因此,作为内存映像写出的结构在别的机器上(甚至是被别的编译器编译之后)不一定能被读回来。
  同时注意如果结构包含任何指针(char*字符串或指向其他数据结构的指针),则只有指针值会被写入文件。当它们再次被读回来的时候可能已经失效。最后为了广泛的可移植性,你必需用“b”标志打开文件。

读写结构体的程序如下:

将结构体写入文件:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef struct {
  4. char c;
  5. int h;
  6. short n;
  7. long m;
  8. float f;
  9. double d1;
  10. char *s;
  11. double d2;
  12. }st;
  13. int main(void)
  14. {
  15. FILE *fp;
  16. st sa,sb;
  17. char *str="abcdefg";
  18. sa.c='K';
  19. sa.h=-3;
  20. sa.n=20;
  21. sa.m=100000000;
  22. sa.f=33.32f;
  23. sa.d1=78.572;
  24. sa.d2=33.637;
  25. sa.s=str;
  26. fp=fopen("st.txt","w+");
  27. if(!fp)
  28. {
  29. printf("errror!\n");
  30. exit(-1);
  31. }
  32. 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);
  33. 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);
  34. fwrite(&sa,sizeof(sa),1,fp);
  35. rewind(fp);
  36. fread(&sb,sizeof(sb),1,fp);
  37. 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);
  38. fclose(fp);
  39. return 0;
  40. }

从文件中读出结构体:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef struct {
  4. char c;
  5. int h;
  6. short n;
  7. long m;
  8. float f;
  9. double d1;
  10. char *s;
  11. double d2;
  12. }st;
  13. int main(void)
  14. {
  15. FILE *fp;
  16. st sb;
  17. fp=fopen("st.txt","r");
  18. if(!fp)
  19. {
  20. printf("errror!\n");
  21. exit(-1);
  22. }
  23. fread(&sb,sizeof(sb),1,fp);
  24. 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);
  25. 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);
  26. fclose(fp);
  27. return 0;
  28. }

在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++ 读写结构体到文件的更多相关文章

  1. Demo02_对结构体进行文件读写_张仕传_作业_

    #include <iostream> using namespace std; #define StructArrarySize 5 // 老师数量 #define StudentNum ...

  2. 在FLASH中读写结构体

    在FLASH中读写结构体 注意事项 编程(写数据)地址要对齐 写数据时,我们要指定写入的地址,如果写入地址为非对齐,则会出现编程对齐错误. 比如遵循32位(4字节)地址对齐,你的地址只能是4的倍数.0 ...

  3. C语言文件读写(结构体文件)

    有时候,我们需要将输入的数据存储起来,这时候就需要用到文件,对于C语言而言,文件的读写有多种方式,下面主要是结构体文件的读写,例如student.dat(第一列是学号,第二列是姓名) xiaoming ...

  4. 结构体:探析C#文件方式读写结构体

    最近直在研究Net Micro Framework字体文件(tinyfnt)由于tinyfnt文件头部有段描述数据所以很想 定义个结构体像VC样直接从文件中读出来省得用流个个解析很是麻烦 没有想到在中 ...

  5. cdev成员结构体file_operations文件操作结构的分析

    struct file_operations{ struct module *owner; // 指向拥有该结构的模块的指针,避免正在操作时被卸载,一般为初始化为THIS_MODULES loff_t ...

  6. C语言中FILE是结构体,文件类型的指针

    c语言文件类型指针 我们在定义文件类型指针变量后,称作该指针指向该文件,但本质上,它不是指向一个存储文件信息的结构型变量么?那么我们在用各个函数对所谓的“文件指针”进行操作时,本质上是不是函数通过获取 ...

  7. C语言博客作业--结构体,文件

    1.本章学习总结(2分) 1.1 学习内容总结 (1)结构体如何定义.成员如何赋值 结构体的一般形式为:      struct  结构体名     {      数据类型 成员名1:      数据 ...

  8. 几年前做家教写的C教程(之五专讲结构体与文件操作)

    C语言学习宝典(5) 结构体: 将不同类型的数据组合成为一个有机的整体,这个整体就是一个结构体. 例如: Struct student { Int name; Char sex; Float scor ...

  9. Delphi基础Write写入结构体到文件(使用 file of myrecord就行了,真简单)

    program WriteStruct; {$APPTYPE CONSOLE} uses SysUtils; //写入结构体 type TCustomer = record ID: ]; Code: ...

随机推荐

  1. laravel5.5打印sql语句

    额.其实laravel很不方便的地方就是sql写错之后不是很好调试. 上方法. //DB::connection()->enableQueryLog(); // 开启QueryLog//$rep ...

  2. pandas数据清洗

    1.我已安装好Anavonda3.5.所以我只用打开"jupyter notebook",然后打开浏览器 然后点击右侧的“new",然后打开python3

  3. SpringCloud---客户端负载均衡---Spring Cloud Ribbon

    1.概述 1.1 Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具: 基于Netflix Ribbon实现: 通过Spring Cloud的封装,可以轻松将面向服务 ...

  4. Oracle 维护数据的完整性 一 约束

    简介:约束用于确保数据库满足特定的商业规则.在Oracle中,约束包括以下几种: 1.not null      非空约束       该劣质不能为null 2.unique       唯一约束   ...

  5. Android捕捉图像后在SurfaceView上变形显示问题的处理

    我们在Android中经常会使用SurfaceView编写自定义的摄像头,可是有的时候会经常会出现图像的变形,我们就会很郁闷的问这到底是为什么呢?其实这个最根本的原因是SurfaceView和PreV ...

  6. spring 配置文件被加载两次

    如下web.xml示例: 1.用spring的配置加载contextConfigLocation 2.配置spring-mvc的contextConfigLocation <servlet> ...

  7. r.js 配置文件 example.build.js 不完整注释

    /* * This is an example build file that demonstrates how to use the build system for * require.js. * ...

  8. 计算F1Score

    计算F1Score predictions = pval < epsilon fp = sum((predictions == 1) & (y == 0)) fn = sum((pred ...

  9. lighttpd 与 gitweb 搭建服务器

    搭建 Git 仓库服务器 下载 gitweb 如果是用 debian 系的 Linux 发行版,可以使用 apt 下载安装可执行的 gitweb sudo apt-get install gitweb ...

  10. log4j 简单用法

    maven添加必要库: <!-- https://mvnrepository.com/artifact/log4j/log4j --> <dependency> <gro ...