读取二进制文件并将其存储到 c 中的结构

Reading binary file and storing it to struct in c

我正在尝试创建一个软件来存储 wav 文件的元数据。

这是一个 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;

}

这里的问题是"ChunkID"、"Format"和"Subchunk1ID"的输出:

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

只有那些字符串受到这个问题的影响。整数不是。

"ChunkID" 应该只是 "RIFF","Format" 应该只是 "WAVE","Subchunk1ID" 应该是 "fmt ".

我在读取文件时出了什么问题?

PS 抱歉,代码太长了,但这是我认为最小的唯一方式。

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

我认为 fread 函数是你的问题。如果结构有填充但写入数据时没有填充,则数据无法像您那样读取。

在这种情况下,您必须读取结构的每个元素,例如,使用 fscanf.

您可以查看从WAV文件中读取数据的示例:Parsing a WAV file in C and Reading and processing WAV file data in C/C++

从文件中读取结构的其他链接可能对您有所帮助:

fread into struct reads data incorrectly

How to fread() structs?

经过三个小时的研究,我最终得出结论,问题是缺少 NUL 终止符。 Using printf with a non-null terminated string

这解决了我的问题:

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