Fread가 EOF에 일찍 도달하는 이유는 무엇입니까?
문제
파일을 메모리에 읽는 C 라이브러리를 작성하고 있습니다. 파일의 첫 54 바이트 (헤더)를 건너 뛰고 나머지를 데이터로 읽습니다. FSEEK를 사용하여 파일의 길이를 결정한 다음 Fread를 사용하여 파일에서 읽습니다.
루프는 한 번 실행 된 다음 EOF에 도달하기 때문에 종료됩니다 (오류 없음). 결국, BytesRead = 10624, ftell (stream) = 28726 및 버퍼에는 28726 값이 포함되어 있습니다. Fread가 30,000 바이트를 읽고 EOF에 도달하면 파일 위치가 30054가 될 것으로 기대합니다.
C는 내 모국어가 아니므로 어딘가에 멍청한 초보자 실수가 있다고 생각합니다.
코드는 다음과 같습니다.
const size_t headerLen = 54;
FILE * stream;
errno_t ferrno = fopen_s( &stream, filename.c_str(), "r" );
if(ferrno!=0) {
return -1;
}
fseek( stream, 0L, SEEK_END );
size_t bytesTotal = (size_t)(ftell( stream )) - headerLen; //number of data bytes to read
size_t bytesRead = 0;
BYTE* localBuffer = new BYTE[bytesTotal];
fseek(stream,headerLen,SEEK_SET);
while(!feof(stream) && !ferror(stream)) {
size_t result = fread(localBuffer+bytesRead,sizeof(BYTE),bytesTotal-bytesRead,stream);
bytesRead+=result;
}
사용하는 참조에 따라 모드 플래그에 "B"를 추가하는 것이 답입니다. Bonehead-Badge에 대한 지명을 찾고 있습니다. :-)
이 참조 두 번째 단락, 두 번째 문장에서 그것에 대해 이야기합니다 (테이블에 있지는 않지만).
MSDN 페이지의 중간 쯤까지 바이너리 플래그를 논의하지 않습니다.
오픈 그룹 "B"태그의 존재를 언급하지만 "효과가 없을 것"이라고 말합니다.
해결책
아마도 이진 모드 문제 일 것입니다. 파일을 열어보십시오 "r+b"
모드로.
편집하다: 의견에 언급 된 바와 같이 "rb"
그 이후로 원래 의도와 더 잘 어울릴 것입니다. "r+b"
읽기/쓰기를 위해 열립니다 "rb"
읽기 전용입니다.
다른 팁
또한 Binmode.obj를 링크 명령에 포함 시키면 모든 파일이 열리는 경우이를 수행 할 수 있습니다.
이전 답변을 기반으로 한 솔루션 :
size_t bytesRead = 0;
BYTE* localBuffer = new BYTE[bytesTotal];
fseek(stream,headerLen,SEEK_SET);
while(!feof(stream) && !ferror(stream)) {
size_t result = fread(localBuffer+bytesRead,sizeof(BYTE),bytesTotal-
bytesRead,stream);
bytesRead+=result;
}