¿Por qué el ftell devuelve 0 en esta función?
Pregunta
Cuando ejecuto mi programa y me elija para ver la lista de productos, no imprime nada.Después de algún tiempo, me enteré de que el valor de fl_size
siempre es 0.¿Por qué es esto?
void view_prdct_code_list() {
FILE *stock = fopen("stock.dat","r+");
assert(stock);
int fl_size=ftell(stock);
int prd_size= sizeof(product);
int quantity= fl_size/prd_size;
printf("fl_size=%d",fl_size);
fseek(stock,0,SEEK_SET);
prdct cprd= (product *)malloc (sizeof(product)*quantity);
assert(cprd);
int i;
fread(cprd,prd_size,quantity,stock);
for (i=0;i<quantity;i++){
printf("PRODUCT CODE: %d\n",cprd->code);
}
free(cprd);
fclose(stock);
}
Solución
ftell
no devuelve el tamaño total del archivo;devuelve el actual leer o escribir posición dentro del archivo.Llame ftell
inmediatamente después de abrir el archivo, por lo que la posición es el principio del archivo.Usted puede utilizar fseek(stock, 0, SEEK_END)
para buscar hasta el final antes de llamar ftell
, o usted puede bajar una capa y uso fstat(fileno(stock))
para recuperar el tamaño del archivo directamente desde el sistema operativo.
Notas adicionales:
- Ninguna de estas opciones si usted está leyendo de una tubería.(En general, usted necesita para comprobar el éxito de cada uno de su archivo de operaciones de acceso.)
fread
no está garantizado para leer el archivo completo en un solo trago, incluso, si se solicita.- Como 'alk' señala,
ftell
devuelve unlong
, noint
. - Usted debe ser la apertura de este aparentemente-archivo binario con el modo de
"r+b"
. - Los archivos binarios con ningún archivo de encabezado (y, en particular, con no número mágico, de , al menos, cuatro bytes, y en el desplazamiento cero) son una Mala Cosa.
- No echamos el valor de retorno de
malloc
.(Es necesario hacerlo en C++, pero en C no es sólo innecesario, se puede ocultar errores.)
Otros consejos
Revise la página man para ftell
, por ejemplo este: http://linux.die.net/man/3/ftell
Aquí es la parte pertinente: "El ftell() función obtiene el valor actual del indicador de posición de archivo para el stream apuntado por stream".
Al abrir el archivo, la posición del cursor estará en el inicio.Lo que la distancia desde la salida será cero.Por lo tanto ftell
devuelve cero.
Para encontrar el tamaño de archivo, consulte este enlace: ¿Cómo puedo obtener el tamaño de un archivo en C?.He aquí un fragmento en corto:
fseek(fp, 0L, SEEK_END);
sz = ftell(fp);
Asegúrese de llamar fseek(fp, 0L, SEEK_SET);
después de más arriba.
Because ftell
returns the size from the beginning to the current position of the file.
fseek(stock,0,SEEK_SET);
Means you set the position to the first bite of the file.
Also you gotta set fl_size=ftell(stock);
after the fseek
.