¿Cuál es la diferencia entre fgetpos/fsetpos y ftell/fseek?

5 minutos de lectura

¿Cual es la diferencia entre fgetposfsetpos y ftellfseek
carloslipps

¿Cuál es la diferencia entre usar las funciones fgetpos() y fsetpos() y usando las funciones ftell() y fseek() obtener y establecer una posición en un archivo?

Qué son fgetpos() y fsetpos() ¿bueno para? ¿Por qué se usarían en lugar de ftell() y fseek()?

  • Consulte stackoverflow.com/questions/12119132/… ​​Su respuesta es mucho mejor que la respuesta aceptada aquí.

    – Mecki

    24/06/2015 a las 23:39

Ninguna de las respuestas anteriores es correcta – de hecho si usas fsetpos indistintamente con fseek podría introducir una falla de seguridad (https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=20087255).

La razón es que el fpos_t *pos argumento a fsetpos en realidad no es un número entero, por lo que no se puede usar para buscar ubicaciones arbitrarias en un archivo. Por lo tanto, los únicos valores válidos son los obtenidos a partir de fgetpos. Como dicen los documentos,

El indicador de posición del archivo interno asociado con la secuencia se establece en la posición representada por posque es un puntero a un fpos_t objeto cuyo valor habrá sido obtenido previamente por una llamada a fgetpos.

(http://www.cplusplus.com/reference/cstdio/fsetpos/)

Si todo lo que desea es la capacidad de buscar ubicaciones arbitrarias más allá del límite de 32 bits, entonces use ftello / fseeko y compilar con #define _FILE_OFFSET_BITS 64.

  • En realidad, no es una respuesta exacta para la pregunta, ¡pero es muy buena como sugerencia! ¡Gracias!

    – me gusta

    17 de febrero de 2014 a las 2:36

  • @likern Esta es exactamente la respuesta a la pregunta. Y también es la respuesta correcta, la respuesta aceptada es absolutamente incorrecta, como fpos_t puede no ser un número entero (el estándar no requiere que lo sea).

    – Mecki

    24 de junio de 2015 a las 23:36

  • ftello y fseeko son funciones POSIX. Además, el estándar C11 establece en 7.21.9.1: “La función fgetpos almacena los valores actuales del estado de análisis (si lo hay) y el indicador de posición del archivo para la secuencia a la que apunta la secuencia en el objeto al que apunta pos” Además: en 7.21. 1 se dice:”fpos_t que es un tipo de objeto completo que no sea un tipo de matriz capaz de registrar toda la información necesaria para especificar de forma única cada posición dentro de un archivo”. Sin embargo, al menos en mi sistema fpos_t es un __darwin_off_t que resulta ser un __int64_t. Use fsetpos y fgetpos cuando sea posible

    – Matemáticas

    3 de mayo de 2016 a las 8:37


  • No puedo abrir el enlace :/ ¿Alguna copia del razonamiento?

    – Llama de fuego

    2 de diciembre de 2019 a las 14:28

  • No diré que esto está mal, porque no lo sé, pero cada vez que he seguido el consejo de Confluence sobre los posibles riesgos de seguridad de C, han estado equivocados.

    – Cazador Kohler

    10 de agosto de 2021 a las 16:24

Bueno, en la página de manual podemos ver que ftell y fseek usan type long int para representar compensaciones (posiciones) en un archivo y, por lo tanto, pueden limitarse a compensaciones que pueden representarse en un int largo. (No se garantiza que el tipo int largo contenga valores superiores a 2**31-1, lo que limita el desplazamiento máximo a 2 gigabytes). Las funciones fgetpos y fsetpos más nuevas, por otro lado, usan un typedef especial, fpos_t, para representar las compensaciones. El tipo detrás de este typedef, si se elige correctamente, puede representar compensaciones arbitrariamente grandes, por lo que fgetpos y fsetpos se pueden usar con archivos arbitrariamente grandes. fgetpos y fsetpos también registran el estado asociado con flujos multibyte.

  • ¡Esta respuesta es incorrecta! Si solo quieres buscar más allá 2**31-1 entonces hay fseeko. La respuesta correcta es que fgetpos sólo puede aspirar a un puesto previamente obtenido por fgetpos y eso fpos_t no debe interpretarse como un número entero, como dice la página del manual: En algunos sistemas que no son UNIX, un objeto fpos_t puede ser un objeto complejo y estas rutinas pueden ser la única forma de reposicionar de forma portátil un flujo de texto.

    – Mecki

    24/06/2015 a las 23:33


  • @Mecki Sí, de hecho, esta respuesta es incorrecta. Por lo que entiendo, mi respuesta a continuación es la única correcta.

    – HughHughTeotl

    26 de junio de 2015 a las 7:24

  • No, la respuesta no es incorrecta pero sí insuficiente. Establece correctamente los límites de fseek y amigos, y correctamente dice que fgetpos y los amigos son una opción que no tiene esos límites. La respuesta anterior nunca dice que puedes mezclar fseek y fsetpos y amigos, lo cual es ciertamente peligroso. Además, nunca dice que fpos_t es de tipo integral. En cambio, Mecki sugiere fseeko y amigos que no son funciones estándar ISO-C (pero funciones POSIX).

    – Matemáticas

    3 de mayo de 2016 a las 8:46

fgetpos() va con fsetpos(). Y ftell() va con fseek().

fgetpos() se parece prácticamente a ftell() porque ambos toman un parámetro FILE* y ambos devuelven algún tipo de posición en el archivo, aunque con un estilo ligeramente diferente. Pero escuche esto: SOLO fseek() le permite buscar desde el principio del archivo, desde su posición actual en el archivo y hacia atrás desde el final del archivo (el tercer argumento para fseek() es SEEK_SET, SEEK_CUR y SEEK_END). ). fsetpos() no hace esto. fsetpos() se limita a volver a alguna posición que obtuvo de fgetpos().

Digamos que desea leer un archivo en la memoria. ¿Cuánto montón necesitas de malloc()? Necesitas el tamaño del archivo. Y todavía tengo que encontrar alguna función en la biblioteca estándar de C que le indique el tamaño de un archivo, aunque algunos compiladores de C pueden agregar una función no estándar. Por ejemplo, Borland Turbo C tenía filelength(). Pero no he visto filelength() entre la biblioteca STANDARD C.

Entonces, lo que puede hacer es usar fseek() a 0 bytes antes del FIN del archivo. Luego use ftell() para obtener la posición en bytes, y base su cálculo para la cantidad de memoria de almacenamiento dinámico en eso.

¿Qué más podrías hacer para obtener el tamaño del archivo? Podría usar fgetc() para leer cada carácter, contando hasta llegar al final. Pero creo que usar fseek() y ftell() es mejor y más fácil.

¿Cual es la diferencia entre fgetposfsetpos y ftellfseek
m1tk4

No hay diferencia en la funcionalidad, aunque las interfaces se definen de manera diferente. Ambos están implementados porque ambos son parte de POSIX.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad