2016-08-19 7 views
-1

は、私はとのトラブルを抱えているコードの一部です:fread(fmtChunkId、sizeof(char)、4、fp)はなぜですか? 11文字を読みますか?ここ

fread(fmtChunkId, sizeof(char), 4, fp); 
if(strcmp(fmtChunkId, "WAVE") != 0) { 
    cout << "Not WAVE format: " << fmtChunkId << endl; 
    return 0; 
} 

私はプログラムを実行すると、それは私が交換するとき、それは正常に動作しますが、しかし、11文字の代わりに、4であるNot WAVE format: WAVE    e∞@を印刷しますfmtChunkIdtypeとすると、私はこれらの2つの変数を同じと宣言しているので、混乱します。 Cスタイルの文字列がnull文字\0で終わらなければならないので、

#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; 
} 
+1

、このような問題を解決するための適切なツールは、あなたのデバッガを使用することではなく、あなたがそうする前にスタックオーバーフローで尋ねる。 1つ目の行でコードを検査するときに行ったすべての観察を教えてください。また、[**小さなプログラムをデバッグする方法(Eric Lippertによる)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)**]を読んでみてください。あなたの問題を再現する** [MCVE] **を私たちに任せてください。 (これはπάνταῥεῖ™によって提供される個人的なコメントです) –

+1

ヌル終了。 –

+0

展開するには、char配列に4文字を格納できます。あなたは4文字を読んでいますが、freadがそれをしないので、ヌルバイトを追加する必要があります。 – zachyee

答えて

1

"WAVE"文字列リテラルは、実際には5バイト長です。 typefmtChunkIdを4文字のみで宣言しているので、strcmp関数とcout <<文は、実際には4バイトの末尾を超えて、\0になるまで読み込みます。 (承認されていないメモリが実行される前に\0に当たってもsegfaultが発生する可能性があります)。

したがって、fmtChunkIdとすると、それは次の\0の前にメモリ内で見つかったものなので、ごみの数文字を印刷します。 typeでは、次のバイトは\0であったため、誤って作業しました。

解決策の1つは、文字列を長さ5に初期化し、freadの後、最後にstrcmpの後に最後のバイトを0に設定することです。

より雄弁ソリューションは、文字列の代わりに(あなたが本当に欲しいものである)を直接バイトを比較する、memcmpを使用することです:

fread(fmtChunkId, sizeof(char), 4, fp); 
if(memcmp(fmtChunkId, "WAVE", 4) != 0) { 
    cout << "Not WAVE format" << endl; 
    return 0; 
} 
関連する問題