我要将一个结构体数组以二进制的方式,写入文件中。
struct NUM
{int a;
 char b[20];
 double c;
}
struct NUM data[5];
.......
fwrite(data,sizeof(struct NUM)*5,1,fp);
结果data[0]中a占4字节,b占20子节,c占8子节,写到文件里都没错
data[1]应该是从文件中的第32个字节开始写起吧,但他却是从第33字节开始写,data[0]与data[1]之间自动空了1`个字节,而且后面也是,data[1]与data[2]也空了一个字节,
我记得不应该空呀。我对这些二进制文件中的指针,字节问题已经懵了,谁能帮我缕清楚。

解决方案 »

  1.   

    编译器对结构元素自动对齐所产生的,是为了运算效率的考虑。一定要自己一位一位地去对,你可以改变这个设置:
    Project->Settings...->C/C++->Category选“Code Generation”->Structure member alignment选“1 Byte”
      

  2.   

    题外话:
    一般,好一点的风格的程序,应该不依赖编译器的设置,所以,对sturcture数组,要取得具体每个元素的地址,最好不要自己去计算,而是让编译器帮你做,比如:NUM *pSecondData = &(data[1]);。
      

  3.   

    题外话:
    一般,好一点的风格的程序,应该不依赖编译器的设置,所以,对sturcture数组,要取得具体每个元素的地址,最好不要自己去计算,而是让编译器帮你做,比如:NUM *pSecondData = &(data[1]);。
      

  4.   

    我理解你所说的“自动对齐”问题象这样
    struct a
    {int b1;
     double b2;
    }由于字节对齐问题,会将int由原来的4个字节,自动定为占8个字节。
    使struct a为16个而不是12个字节。但这里写入文件时每个结构体之间会自动空一个字节,是好像与“自动对齐”无关吧,起码我的Project->Settings...->早就定为“1 Byte”了。
      

  5.   

    你用循环试试
    for(i=0;i<5;i++)
    {
        fwrite(data,sizeof(struct NUM),1,fp);
    }
      

  6.   

    是不是应该这样写?
    fwrite(data,sizeof(struct NUM),5,fp);
      

  7.   

    是不是应该这样写?
    fwrite(data,sizeof(struct NUM),5,fp);
      

  8.   

    在你的程序前面加上#progma pack(1)
      

  9.   

    fwrite(data,1,sizeof(struct NUM)*5,fp);
      

  10.   

    这跟你用的写文件的方式有关。你用这种方式写出来的文件就是这样的。跟对齐方式没有关系。
    fwrite(data,sizeof(struct NUM)*5,1,fp);
    这样使用fwrite函数,就已经假定你会使用fread(data, sizeof(struct NUM)*5, 1, fp)这样的方式来读入数据。试想你来实现fwrite,fread函数,你怎么判断一个结构的结束呢?显然需要额外的数据来表示。没有办法,要想实现你所说的那种存储,像这样。for
      fwrite(data[].member);
      ...
      

  11.   

    fwrite(data,sizeof(struct NUM),1,fp);
      

  12.   

    在你的程序前面加上#progma pack(1)
    也就是在程序的最上面,#include 下面加上这个预编译指令.
    就是以一个字节对齐,中间不六任何空隙。
      

  13.   

    RedFire(丹焰) 真的没有别的简单点的方法了吗?谢谢
      

  14.   

    试想你来实现fwrite,fread函数,你怎么判断一个结构的结束呢?显然需要额外的数据来表示。??为什么需要判断它是否结束,不都是二进制的数据吗?
      

  15.   

    你的fopen函数的参数应该是"wb"和不是"w":fp = fopen( "xxx", "wb" );
      

  16.   

    我建议你用ftream的相关功能,其实很简单,就是在初始化文件流的时候,用iso::binary,就可以任意读写二进制文件,我以微软MFC的名义向你保证不会出错。
      

  17.   

    我按照你说得情况做了
    没有任何的编译设置
    没有你说的空字节vc6 sp5#include <iostream>using namespace std;struct NUM
    {
    int a;
    char b[20];
    double c;
    };struct NUM data[5];int main()
    {
    int nRetCode = 1;
    FILE *stream;
    int i;
    size_t size = sizeof(struct NUM);

    if( (stream = fopen( "fread.out", "wb" )) != NULL )
    {
    for(i=0;i<5;i++)
    {
    data[i].a = i;
    fwrite(&data[i],size,1,stream);
    }
    fclose( stream );
    }
    else
    printf( "Problem opening the file\n" );

    return nRetCode;
    }
      

  18.   

    》data[1]应该是从文件中的第32个字节开始写起吧,但他却是从第33字节开始写就是应该从33字节开始写起,内存寻址是由0开始,而文件不能从零寻址,是从第一个字节开始写起的。:)