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으로 설정했기 때문에 두 변수를 동일하게 선언했기 때문에 혼란 스럽습니다. C 스타일의 문자열은 널 문자 \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

null 종료. –

+0

확장하려면 char 배열에 4자를 저장할 수 있습니다. 당신은 4자를 읽었으나 fread가 당신을 위해 그것을하지 않기 때문에 널 바이트를 덧붙일 필요가있다. – zachyee

답변

1

문자열은 문자 "WAVE"는, 실제로는 5 바이트입니다. typefmtChunkId을 4 개의 문자로 선언 했으므로 strcmp 함수와 cout << 문은 실제로는 \0에 도달 할 때까지 4 바이트의 끝에서부터 계속 읽습니다. (인증되지 않은 메모리가 실행되기 전에 \0에 충돌하지 않으면 segfault가 발생할 수 있습니다).

그래서 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; 
}