读取二进制文件并将其存储到 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);
...
我正在尝试创建一个软件来存储 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);
...