ifstream seekg além final não retorna EOF no VS 2008 Express?
Pergunta
No VS 2005, eu tenho algum código parecido com este:
ifs.open("foo");
while (!ifs.eof())
{
ifs.read(&bar,sizeof(bar));
loc = ifs.tellg();
loc += bar.dwHeaderSize;
// four byte boundary padding
if ((loc % 4) != 0)
loc += 4 - (loc % 4);
ifs.seekg(loc,ios::beg);
}
ifs.close();
O código funcionou bem no VS 2005, mas falha em VS 2008 Express. Do que eu posso dizer, VS 2008 não está retornando eof () após o código de procura para o final do arquivo. Estou esquecendo de algo? Eu fixo-lo adicionando uma verificação explícita para ver se a buscar localização excedeu o tamanho do arquivo, mas eu quero ter certeza eu entendo ifstream corretamente.
Solução
A bandeira EOF só é acionado depois que você tenta ler além do fim do arquivo.
Leitura upto
o fim do arquivo não vai provocá-lo.
É por isso que a maioria dos olhares código como este:
while(ifs.read(&bar,sizeof(bar)))
{
// Do Stuff
}
Se o resultado da leitura () vai até o EOF do loop será inserido.
Se o resultado da leitura () atravessam a EOF o loop não será enetered
- NOTA: read () só vai passar a EOF se existem zero bytes deixados no arquivo. Caso contrário, ele irá ler até o final do arquivo. Assim, o ciclo é sempre inserido se não foi somthing deixado no arquivo.
A razão é o resultado da leitura (o valor de retorno) é uma referência para o fluxo. Se a corrente é utilizado num contexto booleano (tal como a expressão de teste, se) é convertida em um tipo que pode ser usado em tal contexto de um. O resultado desta conversão testa a bandeira EOF (para além de um par de outros) e retorna o quivalent de false se EOF é verdadeiro.
Nota:
Esta técnica funciona melhor se você sobrecarregar o operador << para sua classe Bar como este deve ler exatamente o que ele precisa para o objeto sem ir além da EOF. É então mais fácil fazer seus objetos de ler exatamente até o final do arquivo sem ultrapassar. A coisa me preocupa com leitura é o que deve acontecer se read () quer 10 bytesand há apenas 5 bytes no arquivo, o que acontece com o objeto parcialmente preenchido?
Se você quiser continuar usando o seu estilo o código deve ficar assim:
ifs.open("foo");
while (!ifs.eof())
{
ifs.read(&bar,sizeof(bar));
if (ifs.eof())
{ break;
}
// Do Stuff
}