c - 读取二进制文件并将其存储到 c 中的 struct
问题描述
我正在尝试创建一个存储 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”,“格式”应该只有“WAVE”,“Subchunk1ID”应该是“fmt”。
我在阅读文件时出了什么问题?
PS 对不起,荒谬的长代码,但这是我发现这是最小的唯一方法。
解决方案
经过三个小时的研究,我终于得出结论,问题在于它缺少一个NUL
终结器。使用带有非空终止字符串的 printf
这解决了我的问题:
...
printf("ChunkID: %.*s\n",4,WAV_HEADER.ChunkID);
printf("ChunkSize: %u\n",WAV_HEADER.ChunkSize);
printf("Format: %.*s\n",4,WAV_HEADER.Format);
...
推荐阅读
- javascript - 导入图像文件夹
- python - 只有在熊猫数据框中以数字开头时才添加前导零
- python - pandas to csv - 保留“$”作为格式
- asp.net-mvc-4 - 如何通过网格刷新读取和更新剑道网格页脚模板值
- java - 从我自己的 Android 应用程序单击我的 Google 地图活动中的标记时打开浏览器 url
- django - 如何在 djando 模型中对某些对象使用 on_delete CASCADE,对其他对象使用 ondelete DO_NOTHING
- java - 我的 java 程序为某些 AWT 类抛出 java.lang.ClassNotFoundException 我该怎么办?
- c# - 如何计算 PostgreSQL 中 BEGIN TRANSACTION 语句的数量?
- google-cloud-platform - BigQuery 查询在执行期间试图通过错误的帐户
- python - Andrew Ng 的猫与非猫示例的 Tensorflow 实现 (coursera)