以下是我遇到问题的代码部分:
fread(fmtChunkId, sizeof(char), 4, fp);
if(strcmp(fmtChunkId, "WAVE") != 0) {
cout << "Not WAVE format: " << fmtChunkId << endl;
return 0;
}
当我运行该程序时,它会打印Not WAVE format: WAVE e∞@
,长度为11个字符,而不是4个。但是,当我用fmtChunkId
替换type
时,它会正常工作,这让我很困惑,因为我声明这两个变量是相同的。
#include <iostream>
#include <string.h>
using namespace std;
int main() {
/*Get file path*/
char filepath[261];
cout << "Please enter the file path of a .wav file: ";
cin.getline(filepath, sizeof(filepath));
FILE *fp = NULL;
fp = fopen(filepath, "rb");
if(!fp) {
cout << "Failed to open file: " << filepath;
return 0;
}
cout << endl;
/*Declarations*/
char type[4];
char riffChunkId[4];
int riffChunkSize;
char fmtChunkId[4];
int fmtChunkSize;
short audioFormat;
short numChannels;
int sampleRate;
int byteRate;
short blockAlign;
short bitsPerSample;
int dataSize;
/*Read file data*/
fread(riffChunkId, sizeof(char), 4, fp);
if(strcmp(riffChunkId, "RIFF") != 0) {
cout << "Not RIFF format: " << riffChunkId << endl;
return 0;
}
fread(&riffChunkSize, sizeof(int), 1, fp);
fread(fmtChunkId, sizeof(char), 4, fp);
if(strcmp(fmtChunkId, "WAVE") != 0) {
cout << "Not WAVE format: " << fmtChunkId << endl;
return 0;
}
fread(type, sizeof(char), 4, fp);
if(strcmp(type, "fmt ") != 0) {
cout << "Not fmt: " << type << endl;
return 0;
}
fread(&fmtChunkSize, sizeof(int), 1, fp);
fread(&audioFormat, sizeof(short), 1, fp);
fread(&numChannels, sizeof(short), 1, fp);
fread(&sampleRate, sizeof(int), 1, fp);
fread(&byteRate, sizeof(int), 1, fp);
fread(&blockAlign, sizeof(short), 1, fp);
fread(&bitsPerSample, sizeof(short), 1, fp);
fread(type, sizeof(char), 4, fp);
if(strcmp(type, "data") != 0) {
cout << "Not data: " << type << endl;
return 0;
}
fread(&dataSize, sizeof(int), 1, fp);
/*Print file data*/
cout << "RIFF Chunk Size: " << riffChunkSize << endl;
cout << "fmt Chunk Size: " << fmtChunkSize << endl;
cout << "Audio Format: " << audioFormat << endl;
cout << "Number of Channels: " << numChannels << endl;
cout << "Sample Rate: " << sampleRate << endl;
cout << "byteRate: " << byteRate << endl;
cout << "blockAlign: " << blockAlign << endl;
cout << "Bits Per Sample: " << bitsPerSample << endl << endl;
return 0;
}
答案 0 :(得分:1)
字符串文字"WAVE"
实际上是5个字节长,因为C风格的字符串必须以空字符\0
结尾。由于您仅使用4个字符声明type
和fmtChunkId
,因此strcmp
函数和cout <<
语句实际上会一直读取超过4个字节的结尾,直到它达到{{1 }}。 (如果它在遇到未经授权的内存之前没有遇到\0
,则会导致段错误。)
因此,对于\0
,它打印出一些额外的垃圾字符,因为它是在下一个fmtChunkId
之前在内存中找到的内容。使用\0
时,下一个字节恰好是type
,因此无意中有效。
正如其他评论者所提到的,一个解决方案是将字符串初始化为5的长度,并在\0
之后但fread
之前将最后一个字节设置为0。
更有说服力的解决方案是使用memcmp
,它直接比较字节(这是你真正想要的)而不是字符串:
strcmp