2016-08-19 67 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; 
} 

當我運行程序時,它打印Not WAVE format: WAVE    e∞@這是長期的,而不是4。但是11個字符,它工作正常,當我更換fmtChunkIdtype,這混淆了我,因爲我聲明這兩個變量相同。

#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

解決這些問題的最佳工具是使用調試器,但不在你這樣做之前先問Stack Overflow。告訴我們您在檢查您的代碼時所做的所有觀察。您也可以閱讀[**如何調試小程序(由Eric Lippert撰寫)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)**] At最少給我們留下一個** [MCVE] **,它可以再現您的問題。 (這是個人評論由πάνταῥεῖ™提供) –

+1

無效終止。 –

+0

要展開,您的char數組可以包含4個字符。你讀了4個字符,但也需要附加一個空字節,因爲fread不會爲你做。 – zachyee

回答

1

的字符串文字"WAVE"實際上是5個字節長,因爲C風格的字符串必須以空字符\0結束。既然你宣佈typefmtChunkId只有4個字符,在strcmp功能和cout <<聲明實際上是繼續讀過去的4個字節的結束,直到它擊中\0。 (如果它在運行到未授權的內存之前未碰到\0,則會導致段錯誤)。

因此,與fmtChunkId,它打印出一些額外的垃圾字符,因爲這是它在下一個\0之前發現的內存中。隨着type,下一個字節正好是\0,所以它偶然的工作。

正如其他評論者所提到的,一種解決方案是將字符串初始化爲5,然後在fread之後但在strcmp之前將最後一個字節設置爲0。

更雄辯解決方案是使用memcmp,這直接比較字節(這是你真正想要的),而不是字符串:

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