Por que é fread atingindo o EOF cedo?
Pergunta
Eu estou escrevendo uma biblioteca C que lê um arquivo para a memória. Ele ignora os primeiros 54 bytes do ficheiro (cabeçalho) e, em seguida, lê o restante na forma de dados. Eu uso fseek para determinar o tamanho do arquivo, e depois usar fread para ler no arquivo.
a execução do loop uma vez e depois termina porque o EOF é atingido (sem erros). No final, bytesRead = 10624, ftell (corrente) = 28726, e o tampão contém 28726 valores. Espero fread para ler 30.000 bytes e a posição do arquivo a ser 30054, quando EOF é atingido.
C não é minha língua nativa, então eu suspeito que eu tenho um lugar iniciante erro estúpido.
código é a seguinte:
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;
}
Dependendo da referência que você usa, é bastante evidente que a adição de um "b" para a bandeira modo é a resposta. Procurando nomeações para o bonehead-crachá. : -)
conversações Esta referência sobre ele no segundo parágrafo, segunda frase (embora não em sua mesa).
MSDN não discute o binário bandeira até no meio da página.
OpenGroup menciona a existência da marca "b", mas Membros de que "não terá nenhum efeito".
Solução
talvez seja uma questão de modo binário. Tente abrir o arquivo com "r+b"
como o modo.
Editar :. Como observado em um comentário "rb"
é provável uma melhor adequação à sua intenção original desde "r+b"
irá abri-lo para leitura / gravação e "rb"
é somente leitura
Outras dicas
Também digno de nota que simplesmente incluindo binmode.obj em seu comando link irá fazer isso por você para todo arquivo é aberto.
Uma solução, com base nas respostas anteriores:
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;
}