2008-10-02 23 views
26

Estoy escribiendo una biblioteca C que lee un archivo en la memoria. Salta los primeros 54 bytes del archivo (encabezado) y luego lee el resto como datos. Utilizo fseek para determinar la longitud del archivo, y luego uso fread para leer en el archivo.¿Por qué Fread llega al EOF temprano?

El bucle se ejecuta una vez y luego finaliza porque se alcanza el EOF (sin errores). Al final, bytesRead = 10624, ftell (stream) = 28726, y el buffer contiene 28726 valores. Espero que haya leído 30,000 bytes y que la posición del archivo sea 30054 cuando se alcance el EOF.

C no es mi lengua materna, así que sospecho que tengo un error tonto para principiantes en alguna parte.

Código es el siguiente:

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; 
} 

Dependiendo de la referencia se utiliza, es bastante evidente que la adición de una "b" para el indicador de modalidad es la respuesta. Buscando nominaciones para el bonehead-badge. :-)

This reference habla de ello en el segundo párrafo, segunda frase (aunque no en su tabla).

MSDN no habla de la bandera binaria hasta la mitad de la página.

OpenGroup menciona la existencia de la etiqueta "b", pero indica que "no tendrá ningún efecto".

+0

I añadido la etiqueta Microsoft desde fopen_s es sólo en RTL de MS C. – user7116

+0

OpenGroup lo menciona: r o rb - Abrir archivo para leer. ... El carácter 'b' no tendrá ningún efecto, pero está permitido para la conformidad con el estándar ISO C. Por favor arregla tu edición –

+0

Quité la etiqueta de Microsoft. –

Respuesta

48

quizás es un problema de modo binario. Intente abrir el archivo con "r+b" como modo.

EDITAR: como se señala en un comentario es probable "rb" una mejor adaptación a su intención original desde "r+b" la abrirá para lectura/escritura y "rb" es de sólo lectura.

+0

Pseudo +1 (No tengo votos) –

+0

+1 para Mike F y para mí. Windows me muerde con + b todo el tiempo. – user7116

+0

Sugeriría probar "rb" primero, ya que "r + b" abre el archivo para lectura y escritura, y si no tiene la intención de escribir en el archivo, debe continuar abriendo como de solo lectura. –

0

También vale la pena señalar que simplemente incluir binmode.obj en su comando de enlace hará esto por usted para todos los archivos abiertos.

-1

una solución, sobre la base de las respuestas 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; 
} 
Cuestiones relacionadas