2008-09-28 14 views
8

Muy pocas palabras, tengo el siguiente fragmento de código:final del archivo * puntero no es igual al tamaño de los datos escritos

FILE* test = fopen("C:\\core.u", "w"); 
printf("Filepointer at: %d\n", ftell(test)); 
fwrite(data, size, 1, test); 
printf("Written: %d bytes.\n", size); 
fseek(test, 0, SEEK_END); 
printf("Filepointer is now at %d.\n", ftell(test)); 
fclose(test); 

y se da salida:

Filepointer at: 0 
Written: 73105 bytes. 
Filepointer is now at 74160. 

¿Por qué? ¿Por qué el número de bytes escritos no coincide con el puntero del archivo?

+2

Recomiendo no utilizar las rutas de estilo NT en los argumentos fopen(). Windows también admite rutas POSIX, que son portátiles y no requieren escaparse '\'. – Terminus

Respuesta

19

Como abre el archivo en modo texto, convertirá los marcadores de fin de línea, como LF, en CR/LF.

Esto es probable si está ejecutando en Windows (y probablemente lo sea, dado que su nombre de archivo comienza con "c:\").

Si abre el archivo en modo de "wb", sospecho encontrará los números son idénticos:

FILE* test = fopen("C:\\core.u", "wb"); 

El estándar C99 tiene esto que decir en 7.19.5.3 The fopen function:

El modo de argumento apunta a una cadena. Si la cadena es una de las siguientes, el archivo es abierto en el modo indicado. De lo contrario, el comportamiento no está definido.

r archivo de texto abierto para lectura
w truncado a cero longitud o crear un archivo de texto para escribir
a anexados; abrir o crear un archivo de texto para escribir en el archivo binario abierta EOF
rb para leer
wb truncado a cero longitud o crear el archivo binario para escribir
ab anexados; abrir o crear el archivo binario para escribir al final de su archivo-
r+ archivo de texto abierto para la actualización (lectura y escritura)
w+ truncado a cero longitud o crear un archivo de texto para la actualización
a+ anexados; abrir o crear un archivo de texto para la actualización, la escritura en archivo binario abierta EOF
r+b o rb+ para la actualización (lectura y escritura)
w+b o wb+ elimina si existe o crear el archivo binario para actualización
a+b o ab+ adjuntar; abrir o crear un archivo binario para actualización, escribiendo al final de su archivo-

Se puede ver que distinguen entre w y wb. No creo que una implementación sea requirió para tratar los dos de manera diferente, pero generalmente es más seguro usar el modo binario para datos binarios.

+1

Este es un rincón bastante oscuro del lenguaje, me temo. Uno tiende a no saber que está ahí hasta que han sido mordidos por él. ¡Buena atrapada! – fbrereto

+0

Vale la pena señalar que POSIX requiere la implementación ** para no ** tratarlos de manera diferente. –

0

¿qué devuelve fwrite? normalmente el valor de retorno debe ser el número de bytes escritos. Además, ¿qué responde ftell() con justo antes del fseek?

Puede ser útil saber qué sistema operativo, versión de compilador C y biblioteca C.

0

Un archivopointer es una cookie. No tiene valor. Lo único que puedes usar es buscar el mismo lugar en un archivo. Ni siquiera estoy seguro de si ISO C garantiza que ftell devuelve valores crecientes. Si no crees esto, mira los diferentes modos seek(). Existen precisamente porque la posición no es una simple compensación de bytes.

+0

Sí, pero tienen que implementarse * de alguna manera *. Incluso si no está especificado en el estándar, los punteros de archivo serán simples compensaciones de bytes en muchas implementaciones, por lo que es excesivamente pedante decir que no tiene ningún valor. – Tom

+0

No es una cookie. Es un desplazamiento de bytes en modo binario. El modo de texto es un infierno y casi no garantiza que nada funcione en absoluto, y simplemente no debería usarse. –

+0

@R ..: indique la parte del estándar C que lo garantiza. Incluso el modo byte es una extensión POSIX. – MSalters

0

Windows realmente no escribe todos los datos en el archivo sin una descarga y posiblemente una fsync. Tal vez por eso

Cuestiones relacionadas