简体   繁体   中英

Reading binary file and storing it to struct in c

I'm trying to create a software that stores the metadata of a wav file.

Here's an MWE:


#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>

FILE   *  READ_WAV_FILE;

struct WAV_FILE_HEADER{
   char      ChunkID[4];     // RIFF
   uint32_t  ChunkSize;
   char      Format[4];      // WAVE
   char      Subchunk1ID[4]; // fmt
   uint32_t  Subchunk1Size;
   uint16_t  AudioFormat;
   uint16_t  NumChannels;
   uint32_t  SampleRate;
   uint32_t  ByteRate;
   uint16_t  BlockAlign;
   uint16_t  BitsPerSample;
};

struct WAV_FILE_HEADER WAV_FILE_0;

void print_wav_struct(){
   printf("ChunkID:      %s\n", WAV_FILE_0.ChunkID);
   printf("ChunkSize     %u\n", WAV_FILE_0.ChunkSize);
   printf("Format        %s\n", WAV_FILE_0.Format);
   printf("Subchunk1ID   %s\n", WAV_FILE_0.Subchunk1ID);
   printf("Subchunk1Size %u\n", WAV_FILE_0.Subchunk1Size);
   printf("AudioFormat   %hu\n", WAV_FILE_0.AudioFormat);
   printf("NumChannels   %hu\n", WAV_FILE_0.NumChannels);
   printf("SampleRate    %u\n", WAV_FILE_0.SampleRate);
   printf("ByteRate      %u\n", WAV_FILE_0.ByteRate);
   printf("BlockAlign    %hu\n", WAV_FILE_0.BlockAlign);
   printf("BitsPerSample %hu\n", WAV_FILE_0.BitsPerSample);

}

int read_wavfile(){

   READ_WAV_FILE = fopen("read.wav", "rb");
   fseek(READ_WAV_FILE,0,SEEK_SET);
   fread(&WAV_FILE_0,sizeof(WAV_FILE_0),1,READ_WAV_FILE);
   fclose(READ_WAV_FILE);
   return 0;
}
int main(){

   if (read_wavfile()){
      printf("Something went wrong\n");
      return -1;
   }
   print_wav_struct();
   return 0;

}

The problem here is the output of "ChunkID", "Format" and "Subchunk1ID":

ChunkID:      RIFFF
ChunkSize     48824390
Format        WAVEfmt
Subchunk1ID   fmt
Subchunk1Size 16
AudioFormat   1
NumChannels   2
SampleRate    48000
ByteRate      192000
BlockAlign    4
BitsPerSample 16

Only those string are affected in this problem. The integers were not.

The "ChunkID" should've been only "RIFF", the "Format" should've been only "WAVE" and "Subchunk1ID" should've been "fmt ".

What I went wrong reading the file?

PS Sorry for the ridiculous long code, but that's the only way I find that's minimal.

 fread(&WAV_FILE_0,sizeof(WAV_FILE_0),1,READ_WAV_FILE);

I think the fread function is your problem. If the structure has padding but the data was written without padding, then the data cannot be read as you've done it.

In this case you have to read each element of the struct, for example, using fscanf .

You can see the examples for reading the data from WAV file: Parsing a WAV file in C and Reading and processing WAV file data in C/C++

Other links for reading struct from the file maybe help you:

fread into struct reads data incorrectly

fread() a struct in c

How to fread() structs?

After three hours of research, I finally concluded that the problem was it's missing a NUL terminator. Using printf with a non-null terminated string

This solved my problem:

...
printf("ChunkID:    %.*s\n",4,WAV_HEADER.ChunkID);
printf("ChunkSize:  %u\n",WAV_HEADER.ChunkSize);
printf("Format:     %.*s\n",4,WAV_HEADER.Format);
...

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