为了学习文件结构,我试图读入一个 .wav 文件并简单地打印有关它的信息。我有一个包含所有定义信息的结构:
typedef struct{
char chunkId[4];
unsigned int chunkSize;
char format[4];
char subchunk1Id[4];
unsigned int subchunk1Size;
unsigned short audioFormat;
unsigned short numChannels;
unsigned int sampleRate;
unsigned int byteRate;
unsigned short blockAlign;
unsigned short bitsPerSample;
char subchunk2Id[4];
unsigned int subchunk2Size;
void *data;
} WavFile;
发生的事情是,每次我fread
浏览文件时,它都会导致我的 c 字符串打印得越来越长。这是一个示例代码片段:
fseek(file, SEEK_SET, 0);
fread(wavFile.chunkId, 1, sizeof(wavFile.chunkId), file);
fread(&wavFile.chunkSize, 1, sizeof(wavFile.chunkSize), file);
fread(wavFile.format, 1,sizeof(wavFile.format), file);
fread(wavFile.subchunk1Id, 1, sizeof(wavFile.subchunk1Id), file);
fread(&wavFile.subchunk1Size, 1, sizeof(wavFile.subchunk1Size), file);
fread(&wavFile.audioFormat, 1, sizeof(wavFile.audioFormat), file);
printf("%s\n",wavFile.chunkId);
printf("%d\n",wavFile.chunkSize);
printf("%s\n",wavFile.format);
printf("%s\n",wavFile.subchunk1Id);
printf("%d\n",wavFile.subchunk1Size);
printf("%d\n",wavFile.audioFormat);
我的 struct
设置方式、我读取文件的方式或 printf()
查看字符串的方式导致了输出打印如下所示:
RIFF�WAVEfmt
79174602
WAVEfmt
fmt
16
1
预期输出:
RIFF
79174602
WAVE
fmt
16
1
我确实理解 C 字符串需要以 null 终止,但后来我开始思考从二进制文件打印字符串与打印字符串文字有何不同 printf("test");
? 文件规范要求成员的大小具有在我的 struct
中定义的确切大小。执行 char chunkId[5];
然后执行 chunkId[4]='\0';
似乎不是解决此问题的好方法。
几天来我一直在努力解决这个问题,所以现在我来 SO 可能会插入正确的方向。
为了全面披露,这里是文件相关部分的十六进制输出,因为此网络表单没有显示我的输出中出现的所有乱码。
52 49 46 46 CA 1B B8 04 57 41 56 45 66 6D 74 20 10 00 00 00 01 00 02 00 44 AC 00 00 98 09 04 00 06 00 18 00 64 61 74 61
如果知道大小,可以限制printf
的输出:
// Only prints 4-bytes from format. No NULL-terminator needed.
printf("%.4s\n", wavFile.format);
如果大小存储在不同的字段中,您也可以使用它:
// The * says: print number of chars, as dictated by "theSize"
printf("%.*s\n", wavFile.theSize, wavFile.format);
我是一名优秀的程序员,十分优秀!