
Problema con fseek();
Publicado por Diego (150 intervenciones) el 09/07/2016 17:49:44
BUenas tardes, tengo un problema y no logro saber el porqué.
Como no se bien como es que quedan las posiciones de un archivo tras una lectura o escritura.
Decidí guardar la posicion que tiene el archivo antes de que lea o escriba y luego que termine de leer/escribir con fseek hago que retorne a la posicion previamente guardada.
Este es el codigo:
Estos son los datos arrojados por consola:
posicion = 27
posicion = 31
posicion = 35
posicion = 43
posicion = 51
i
m
a
g
e
n
.
j
p
g
posicion = 51
se volvio a la posicion: 62
tamanio cadena = 10
nombre obtenida: @����@
nombre del archivo de salida = @����@
DESEMPAQUETAMIENTO EXITOSO
No se porqué posicion queda con el valor 62, ya que en posicion se encuentra el valor 51, Porqué cambia este valor.
Me puse a pensar y solo se me ocurrre que no use bien la funcion fseek();
Pero según man fseek;
Yo la implemente casi como rewind. O almenos eso intenté.
Como no se bien como es que quedan las posiciones de un archivo tras una lectura o escritura.
Decidí guardar la posicion que tiene el archivo antes de que lea o escriba y luego que termine de leer/escribir con fseek hago que retorne a la posicion previamente guardada.
Este es el codigo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
int LeerSubCabecera(struct datos *cabecera, FILE **entrada)
{
int leidos, escritos;
long pos;
pos = ftell(*entrada);
printf("posicion = %ld\n", pos);
leidos = fread(&cabecera->tamanio, sizeof(unsigned int), 1, *entrada);
if (leidos != 1){
return 18;
}
pos = ftell(*entrada);
printf("posicion = %ld\n", pos);
leidos = fread(&cabecera->fecha_modificacion, sizeof(unsigned int), 1, *entrada);
if (leidos != 1){
return 18;
}
pos = ftell(*entrada);
printf("posicion = %ld\n", pos);
leidos = fread(&cabecera->reservado1, sizeof(long long), 1, *entrada);
if (leidos != 1){
return 18;
}
pos = ftell(*entrada);
printf("posicion = %ld\n", pos);
leidos = fread(&cabecera->reservado2, sizeof(long long), 1, *entrada);
if (leidos != 1){
return 18;
}
unsigned int tamanio_cadena = 0;
char buffer = 'X';
long posicion = 0;
posicion = ftell(*entrada);
printf("posicion = %ld\n", posicion);
leidos = fread(&buffer, sizeof(char), 1, *entrada);
while ((leidos == 1) && (buffer != '\0')){
++tamanio_cadena;
printf("%c\n", buffer);
leidos = fread(&buffer, sizeof(char), 1, *entrada);
}
if (leidos != 1){
return 18;
}
printf("posicion = %ld\n", posicion);
fseek(*entrada, 0L, posicion);
posicion = ftell(*entrada);
printf("se volvio a la posicion: %ld\n", posicion);
printf("tamanio cadena = %u\n", tamanio_cadena);
++tamanio_cadena;
cabecera->nombre = (char *)malloc(sizeof(char)*tamanio_cadena);
escritos = fread(cabecera->nombre, sizeof(char), tamanio_cadena, *entrada);
printf("nombre obtenida: @%s@\n", cabecera->nombre);
if (escritos != tamanio_cadena){
return 18;
}
return EXIT_SUCCESS;
}
Estos son los datos arrojados por consola:
posicion = 27
posicion = 31
posicion = 35
posicion = 43
posicion = 51
i
m
a
g
e
n
.
j
p
g
posicion = 51
se volvio a la posicion: 62
tamanio cadena = 10
nombre obtenida: @����@
nombre del archivo de salida = @����@
DESEMPAQUETAMIENTO EXITOSO
No se porqué posicion queda con el valor 62, ya que en posicion se encuentra el valor 51, Porqué cambia este valor.
Me puse a pensar y solo se me ocurrre que no use bien la funcion fseek();
Pero según man fseek;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
SINOPSIS
#include <stdio.h>
int fseek( FILE *flujo, long desplto, int origen);
long ftell( FILE *flujo);
void rewind( FILE *flujo);
int fgetpos( FILE *flujo, fpos_t *pos);
int fsetpos( FILE *flujo, fpos_t *pos);
DESCRIPCIÓN
La función fseek mueve el indicador de posición del fichero correspondiente al flujo de datos apuntado por flujo. La nueva posición, medida
en bytes, se obtiene añadiendo desplto bytes a la posición especificada por origen. Si origen es SEEK_SET, SEEK_CUR, o SEEK_END, el
desplazamiento es relativo al comienzo del fichero, a la posición actual, o al final del fichero, respectivamente. Una llamada exitosa a la
función fseek limpia el indicador de fin-de-fichero para el flujo y deshace cualquier efecto de la función ungetc(3) en el mismo flujo.
La función ftell obtiene el valor actual del indicador de posición del fichero para el flujo apuntado por flujo.
La función rewind mueve el indicador de posición del fichero para el flujo apuntado por flujo al principio del fichero. Es equivalente a:
(void)fseek(flujo, 0L, SEEK_SET)
salvo en que el indicador de error para el flujo también se limpia (vea clearerr(3)).
Las funciones fgetpos y fsetpos son interfaces alternativas equivalentes a ftell y fseek (con el origen puesto a SEEK_SET), poniendo y
almacenando el valor actual del desplazamiento desde o en el objeto referenciado por pos. En algunos sistemas no UNIX un objeto fpos_t
puede ser un objeto complejo y estas rutinas pueden ser la única manera de reposicionar un flujo de texto de forma transportable.
VALOR DEVUELTO
La función rewind no devuelve nada. Cuando acaban bien, fgetpos, fseek, y fsetpos devuelven 0, y ftell devuelve el desplazamiento actual.
Cuando acaban mal, devuelve -1 y se pone un valor apropiado en la variable global errno.
ERRORES
EBADF El flujo especificado es tal que no permite el acceso directo.
EINVAL El argumento origen de fseek no era SEEK_SET, SEEK_END, ni SEEK_CUR.
Las funciones fgetpos, fseek, fsetpos, y ftell pueden fallar también y poner un valor en errno para cualquiera de los errores especificados
para las rutinas fflush(3), fstat(2), lseek(2), y malloc(3).
CONFORME A
Las funciones fgetpos, fsetpos, fseek, ftell, y rewind siguen el estándar ANSI X3.159-1989 (``C ANSI'').
VÉASE TAMBIÉN
lseek(2), fseeko(3)
Yo la implemente casi como rewind. O almenos eso intenté.
Valora esta pregunta


0