El puntero de fin de ARCHIVO * no es igual al tamaño de los datos escritos
Pregunta
En pocas palabras, tengo el siguiente fragmento de código:
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 produce:
Filepointer at: 0
Written: 73105 bytes.
Filepointer is now at 74160.
¿Por qué es eso? ¿Por qué el número de bytes escritos no coincide con el puntero del archivo?
Solución
Ya que está abriendo el archivo en modo de texto, convertirá los marcadores de fin de línea, como LF, en CR / LF.
Esto es probable si está ejecutando en Windows (y probablemente sí, dado que su nombre de archivo comienza con " c: \ "
).
Si abre el archivo en el modo " wb "
, sospecho que encontrará que 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 La función fopen
:
El modo 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 leer
w
se trunca a la longitud cero o crea un archivo de texto para escribir
a
append; abrir o crear un archivo de texto para escribir al final del archivo
rb
abre un archivo binario para leer
wb
se trunca en longitud cero o crea un archivo binario para escribir
ab
adjuntar; abrir o crear un archivo binario para escribir al final del archivo
r +
archivo de texto abierto para actualización (lectura y escritura)
w +
se trunca a la longitud cero o crea un archivo de texto para actualizar
a +
adjuntar; abrir o crear un archivo de texto para actualizar, escribiendo al final del archivo
r + b
orb +
abren un archivo binario para actualización (lectura y escritura)
w + b
owb +
truncan a la longitud cero o crean un archivo binario para actualizarloa + b
oab +
adjuntar; abra o cree un archivo binario para actualizar, escriba al final del archivo
Puedes ver que distinguen entre w
y wb
. No creo que se requiera una implementación para tratar los dos de manera diferente, pero generalmente es más seguro usar el modo binario para datos binarios.
Otros consejos
¿qué devuelve fwrite? Normalmente, el valor de retorno debe ser el número de bytes escritos. Además, ¿con qué contesta el ftell () justo antes del fseek?
Puede ser útil saber qué sistema operativo, la versión del compilador de C y la biblioteca de C
.Un filepointer es una cookie. No tiene valor. Lo único para lo que puede usarlo es buscar el mismo lugar en un archivo. Ni siquiera estoy seguro de si ISO C garantiza que ftell devuelva valores crecientes. Si no lo cree, mire los diferentes modos de búsqueda (). Existen precisamente porque la posición no es un simple desplazamiento de bytes.
Windows en realidad no escribe todos los datos en el archivo sin una descarga y posiblemente un fsync. Quizás por eso