用C ++读回结构时将结构写入文件,但值错误

时间:2018-08-27 09:46:11

标签: c++ struct fwrite fread file-header

我编写了一些代码来读取.wav文件,并执行了一些算法,然后将其写入新的.wav文件。我使用一个结构体来代表wav标头,然后再将该结构体写入文件中,并将其中的值都是正确的,但是当我回读时,其中的一些值发生了变化,我不知道为什么,这是我的结构:

struct WavHeader{
    public:
            char RIFF[4]={'R','I','F','F'};
            int32_t size0;
            char  WAVE[4]={'W','A','V','E'};
            char FMT[4]={'f','m','t',' '};
            int32_t size1;
            int16_t fmttag;
            int16_t channel;
            int32_t samplespersec;
            int32_t bytepersec;
            int16_t blockalign;
            int32_t bitsEvrSample;
            char DATA[4]={'d','a','t','a'};
            int32_t size2;

            WavHeader(){
                    size0=0;
                    size1=0;
                    fmttag=0;
                    channel=1;
                    samplespersec=0;
                    bytepersec=0;
                    blockalign=0;
                    bitsEvrSample=0;
                    size2=0;
            }
};

这是我要写入wav的函数(pz忽略WavData):

void MTools::write2Wav(const char* fname,WavData* data,WavHeader* wavhead){
    FILE* fid=fopen(fname,"ab+");
    fwrite(wavhead,1,sizeof(WavHeader),fid);
    fclose(fid);
}

最后一个是我用来读取wav标头的函数:

void MTools::loadWavFile(const char* fname,WavData* ret,WavHeader* head){
    FILE* fp=fopen(fname,"rb");
    size_t result;
    if(fp){
            char id[5];
        format_length,sample_rate,avg_bytes_sec,data_size,bits_per_sample;

            result=fread(id,sizeof(char),4,fp);
            id[4]='\0';

            if(!strcmp(id,"RIFF")){

                    result=fread(&(head->size0),sizeof(int16_t),2,fp);
                    result=fread(id,sizeof(char),4,fp);
                    id[4]='\0';

                    if(!strcmp(id,"WAVE")){
                            result=fread(id,sizeof(char),4,fp);

                            result=fread(&(head->size1),sizeof(int16_t),2,fp);


                            result=fread(&(head->fmttag),sizeof(int16_t),1,fp);

                            result=fread(&(head->channel),sizeof(int16_t),1,fp);

                            result=fread(&(head->samplespersec),sizeof(int16_t),2,fp);

                            result=fread(&(head->bytepersec),sizeof(int16_t),2,fp);

                            result=fread(&(head->blockalign),sizeof(int16_t),1,fp);

                            result=fread(&(head->bitsEvrSample),sizeof(int16_t),2,fp);
                            result=fread(id,sizeof(char),4,fp);

                            result=fread(&(head->size2),sizeof(int16_t),2,fp);


                            ret->size=head->size2/sizeof(int16_t);


                            ret->data=(int16_t*)malloc(head->size2);
                            result=fread(ret->data,sizeof(int16_t),ret->size,fp);
                     }      
                    else{
                            cout<<"Error: RIFF File but not a wave file\n";
                    }       
            }       
    else{   
            cout<<"ERROR: not a RIFF file\n";
    }       
    }
    fclose(fp);

}

在编写之前(使用gdb): enter image description here

写入并回读后: enter image description here

2 个答案:

答案 0 :(得分:3)

您需要像重载loadWavFile一样显式地重写write2wav,因为您永远不知道数据是如何像预期的那样打包(结构对齐问题)的(取决于编译器选项的编译器)。

答案 1 :(得分:1)

您将标头定义为类型的混合,例如int16int32。但是,您只能读取int16值。例如,查看samplespersec。我认为,如果您调整类型,就可以解决。