简体   繁体   中英

Write struct to file but wrong value when read back with C++

I write some code to read .wav file and do some algorithm then write to a new .wav file.I use a struct to stand for wav header,before writing the struct to the file,the values in it are all correct,but when I read back ,some values in it changged,I don't know why,here is my struct:

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

here is my function to write to wav(pz ignore the WavData):

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

The last is my function to read the wav header :

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

}

before writing(with gdb): 在此处输入图片说明

after writing and read back: 在此处输入图片说明

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

You define the header as being a mixture of types, like int16 and int32 . But you only ever read int16 values. For example look at samplespersec . I think if you adjust the types, this might be the fix.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM