Autor
|
Tema: EOF en archivo antes de su verdadero final (Leído 3,921 veces)
|
XafiloX
Desconectado
Mensajes: 130
|
Hola, estoy intentando hacer un programa en C que descubra si un archivo de Word tiene un pie de página...Para ello tengo que buscar una secuencia de de caracteres en el archivo y me he montado una funcioncilla que es la siguiente: int buscar(FILE * fp, char * cadena){ char car; if(longi < 1) return -2; int i=0; int k=0; while((car = fgetc(fp )) != EOF ){ if(car == cadena[i]){ k++; while(i +1<(longi -1) && !feof(fp ) && (car =fgetc(fp )) == cadena [++i ]) k++; if(k == longi-1) return 0; return -1; else i=k=0; } } return -1; }
La he probado con archivos de texto y funciona perfectamente... El problema es que cuando le paso el .doc o .docx deja de buscar antes de llegar al final del archivo...he abierto el .doc con un editor hexadecimal y me he encontrado que dentro del propio archivo hay caracteres con FF y por lo tanto en cuanto se llega allí se cree que es el EOF y termina la búsqueda... ¿Hay alguna forma de detectar que no es el auténtico fin de fichero y continuar la búsqueda?
|
|
|
En línea
|
|
|
|
do-while
Desconectado
Mensajes: 1.276
¿Habra que sacarla de paseo?
|
¡Buenas! Si abres los ficheros en modo texto te puede suceder lo que cuentas. En este caso lo que tienes que hacer es abrirlo en binario y cargar el fichero en un vector dinamico de caracteres y realizar la busqueda sobre dicho vector. Estas dos funciones te ayudaran: unsigned long flen(FILE *f) { unsigned long pos, len; fseek(f , pos , SEEK_SET ); return len; } int cargar_fichero(FILE *f, char **contenido, unsigned logn *nbytes) { if(!(*contenido = (char*) malloc((*nbytes = flen (f )) * sizeof(char)))) return 0; return fread(*contenido , (*nbytes ) * sizeof(char) , 1 , f ); }
Ahora podras realizar las busquedas sobre el contenido del vector. Pero aunque modifiques el vector para terminar en '\0' no te aconsejo usar las funciones de manejo de cadenas, ya que tambien podria haber caracteres nulos antes del final del fichero. Puedes utilizar las de manejo de memoria con cuidado de no sobrepasar los limites del fichero... ¡Saludos!
|
|
|
En línea
|
- Doctor, confundo los números y los colores. - Vaya marrón. - ¿Marrón? ¡Por el culo te la hinco!
|
|
|
XafiloX
Desconectado
Mensajes: 130
|
OK, muchísimas gracias por la ayuda!
|
|
|
En línea
|
|
|
|
XafiloX
Desconectado
Mensajes: 130
|
Llevo toda la tarde intentándolo hacer funcionar, pero por algún motivo el fread parece que no funciona, porque ft no tiene el inicio del texto del archivo... He probado todo lo que se me ha ocurrido y no he conseguido nada...fread devuelve que ha leido el número de caracteres correcto, pero luego nada, no están los caracteres que deberían estar... Pongo aquí el código que tengo hecho (es posible que esté un poco guarrete de tanto poner printf's)... #include <stdio.h> #include <stdlib.h> #include <string.h> int buscar(char * ft, char * cadena, unsigned long * bytes); unsigned long flen(FILE *f); int cargar_fichero(FILE *f, char *contenido, unsigned long *nbytes); int main (int argc, char* argv[]){ int i; FILE * fp; char * ft; int a; unsigned long bytes; char data[] = {0x0D, 0x0C, 0x0D, 0x0D, 0x03, 0x0D, 0x0D, 0x04, 0x0D, 0x0D, 0x03, 0x0D, 0x0D, 0x04, 0x0D, 0x0D, 0x00}; for(i=1; i < argc; ++i){ fp = fopen(argv [i ], "rb"); if(fp != NULL){ if((a=cargar_fichero(fp, ft, &bytes)) == 0) return -1; if(buscar(ft, "footnotes.xml", &bytes) == 0) else{ fseek ( fp , 0 , SEEK_SET ); //Devolvemos puntero al inicio if(buscar(ft, data, &bytes) == 0) } return 0; }else printf("No se ha podido abrir el archivo %s", argv [i ]); } return 0; } /* Busca en el archivo la cadena indicada (imitiendo el \0) */ int buscar(char * ft, char * cadena, unsigned long * bytes){ if(longi < 1) return -2; int i=0; int k=0; while(i < *bytes ){printf("Va bien con c=%x, k=%d\n", ft [i ], k ); if(ft[i] == cadena[k]){ k++; while(k < longi && ++i < *bytes && ft[i] == cadena[k]) k++; if(k == longi) return 0; else if(i >= *bytes){ return -1; }else{ k=0; } }else ++i; } return -1; } unsigned long flen(FILE *f){ unsigned long pos, len; fseek(f , pos , SEEK_SET ); return len; } int cargar_fichero(FILE *f, char *contenido, unsigned long *nbytes){ if((contenido = (char*) malloc((*nbytes = flen (f )) * sizeof(char))) == NULL ) return 0; return fread(contenido , sizeof(char) , (*nbytes /sizeof(char)) , f ); }
|
|
|
En línea
|
|
|
|
do-while
Desconectado
Mensajes: 1.276
¿Habra que sacarla de paseo?
|
¡Buenas!
Eso te pasa por modificar el codigo que puse.
El segundo parametro de la funcion cargar_fichero tiene que ser un puntero a un puntero, sino es imposible modificar un puntero exterior a la funcion (variables globales a parte...), que es lo que te hace falta. Y, por cierto, cuando acabes de usar el vector que contiene los datos tendras que liberar la memoria utilizada.
¡Saludos!
|
|
|
En línea
|
- Doctor, confundo los números y los colores. - Vaya marrón. - ¿Marrón? ¡Por el culo te la hinco!
|
|
|
XafiloX
Desconectado
Mensajes: 130
|
Jeje, esta tarde me he dado cuenta de eso...a partir de ahora seguiré la máxima de no tocarás código ajeno He conseguido echar a andar el código pero he tenido que poner todo el código de la función cargar_fichero en el main porque no consigo llamar correctamente a la función... La verdad es que todavía estoy intentando terminar de entender los punteros... Yo a tu función cargar fichero la llamo más o menos así: FILE * fp = fopen(argv [i ], "rb");char ** contenido; unsigned long bytes; cargar_fichero(f, contenido, &bytes);
y después a buscar le paso buscar(*ft, cadena, &bytes)
¿Qué es lo que estoy haciendo mal con los punteros?, porque me daba un fallo de segmentación creo que en el malloc...por eso he puesto el código de la función en el main y en vez de crear contenido como un char ** lo he creado como un char * y así si que he conseguido que funcionase... Muchas gracias por la ayuda!
|
|
|
En línea
|
|
|
|
rir3760
Desconectado
Mensajes: 1.639
|
El "char **" que espera la funcion "cargar_fichero" debe ser la direccion en memoria de la variable de tipo "char *" que almacenara la direccion del bloque: FILE *fp = fopen(argv [i ], "rb");char *contenido; unsigned long bytes; cargar_fichero(f, &contenido, &bytes);
Ello para que asi se puede modificar la variable "contenido" dentro de la funcion "cargar_fichero" (es la emulacion del paso por referencia en C). Un saludo
|
|
|
En línea
|
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly. -- Kernighan & Ritchie, The C programming language
|
|
|
do-while
Desconectado
Mensajes: 1.276
¿Habra que sacarla de paseo?
|
¡Buenas! Por cierto, me he dado cuenta de un gran error en cargar_fichero, antes de leer no sabemos en que posicion se encuentra. Lo correcto seria: int cargar_fichero(FILE *f, char **contenido, unsigned logn *nbytes) { unsigned long posicion; int retorno; if(!(*contenido = (char*) malloc((*nbytes = flen (f )) * sizeof(char)))) return 0; retorno = fread(*contenido , (*nbytes ) * sizeof(char) , 1 , f ); fseek(f , posicion , SEEK_SET ); return retorno; }
¡Saludos!
|
|
|
En línea
|
- Doctor, confundo los números y los colores. - Vaya marrón. - ¿Marrón? ¡Por el culo te la hinco!
|
|
|
XafiloX
Desconectado
Mensajes: 130
|
Muchas gracias a ambos! AL final el programilla que estaba haciendo no ha tenido mucha utilidad, porque no he conseguido encontrar el patrón que sigue para los .docx (si para los .doc), pero aun así me ha servido para aprender algunas cosillas gracias a vuestra ayuda. Un saludo!
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Juicio final cuanto antes
« 1 2 ... 5 6 »
Foro Libre
|
@synthesize
|
58
|
31,516
|
1 Junio 2010, 15:17 pm
por braulio--
|
|
|
SVCHOST.EXE, COMO SABER CUAL ES EL ARCHIVO VERDADERO DEL VIRUS EN EL DISCO DURO
Seguridad
|
JMM13
|
9
|
10,466
|
10 Febrero 2011, 17:54 pm
por JMM13
|
|
|
Firefox 4 Beta 12 antes de la versión final
Noticias
|
wolfbcn
|
1
|
3,166
|
4 Febrero 2011, 15:24 pm
por NachoEx
|
|
|
El escándalo sexual de Giggs desestabiliza al ManU antes de la final contra ...
Foro Libre
|
wolfbcn
|
1
|
3,487
|
24 Mayo 2011, 23:38 pm
por #!drvy
|
|
|
El DNIe 3.0 se emitirá en toda España antes de final de año
Noticias
|
wolfbcn
|
0
|
1,147
|
30 Octubre 2015, 21:44 pm
por wolfbcn
|
|