elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Rompecabezas de Bitcoin, Medio millón USD en premios


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  EOF en archivo antes de su verdadero final
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: EOF en archivo antes de su verdadero final  (Leído 3,905 veces)
XafiloX

Desconectado Desconectado

Mensajes: 130


Ver Perfil
EOF en archivo antes de su verdadero final
« en: 29 Noviembre 2011, 19:47 pm »

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:
Código
  1. int buscar(FILE * fp, char * cadena){
  2.    char car;
  3.    int longi = strlen(cadena);
  4.    if(longi < 1)
  5.        return -2;
  6.    int i=0;
  7.    int k=0;
  8.    while((car = fgetc(fp)) != EOF){
  9.        if(car == cadena[i]){
  10.            k++;
  11.            while(i+1<(longi-1) && !feof(fp) && (car=fgetc(fp)) == cadena[++i])
  12.                k++;
  13.            if(k == longi-1)
  14.                return 0;
  15.            else if(feof(fp))
  16.                return -1;
  17.            else
  18.                i=k=0;  
  19.  
  20.        }
  21.    }
  22.    return -1;
  23.  
  24. }

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 Desconectado

Mensajes: 1.276


¿Habra que sacarla de paseo?


Ver Perfil
Re: EOF en archivo antes de su verdadero final
« Respuesta #1 en: 29 Noviembre 2011, 23:28 pm »

¡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:

Código
  1. unsigned long flen(FILE *f)
  2. {
  3.    unsigned long pos, len;
  4.  
  5.    pos = ftell(f);
  6.    fseek(f , 0 , SEEK_END);
  7.    len = ftell(f);
  8.    fseek(f , pos , SEEK_SET);
  9.  
  10.    return len;
  11. }
  12.  
  13. int cargar_fichero(FILE *f, char **contenido, unsigned logn *nbytes)
  14. {
  15.   if(!(*contenido = (char*) malloc((*nbytes = flen(f)) * sizeof(char))))
  16.        return 0;
  17.  
  18.    return fread(*contenido , (*nbytes) * sizeof(char) , 1 , f);
  19. }
  20.  

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 Desconectado

Mensajes: 130


Ver Perfil
Re: EOF en archivo antes de su verdadero final
« Respuesta #2 en: 30 Noviembre 2011, 00:08 am »

OK, muchísimas gracias por la ayuda!
En línea

XafiloX

Desconectado Desconectado

Mensajes: 130


Ver Perfil
Re: EOF en archivo antes de su verdadero final
« Respuesta #3 en: 30 Noviembre 2011, 18:31 pm »

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)...

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. int buscar(char * ft, char * cadena, unsigned long * bytes);
  6. unsigned long flen(FILE *f);
  7. int cargar_fichero(FILE *f, char *contenido, unsigned long *nbytes);
  8.  
  9. int main (int argc, char* argv[]){
  10.    int i;
  11.    FILE * fp;
  12.    char * ft;
  13.    int a;
  14.    unsigned long bytes;
  15.    char data[] = {0x0D, 0x0C, 0x0D, 0x0D, 0x03, 0x0D, 0x0D, 0x04, 0x0D, 0x0D, 0x03, 0x0D, 0x0D, 0x04, 0x0D, 0x0D, 0x00};
  16.    for(i=1; i < argc; ++i){
  17.        fp = fopen(argv[i], "rb");
  18.        if(fp != NULL){
  19.            if((a=cargar_fichero(fp, ft, &bytes)) == 0)
  20.             return -1;
  21.  
  22.            if(buscar(ft, "footnotes.xml", &bytes) == 0)
  23.                printf("%s\n", argv[i]);
  24.            else{
  25.                printf("\n");
  26.                fseek ( fp , 0 , SEEK_SET ); //Devolvemos puntero al inicio
  27.                if(buscar(ft, data, &bytes) == 0)
  28.                    printf("%s\n", argv[i]);
  29.            }
  30.            return 0;
  31.            fclose(fp);
  32.  
  33.        }else
  34.            printf("No se ha podido abrir el archivo %s", argv[i]);
  35.  
  36.    }
  37.    return 0;
  38. }
  39. /*
  40.     Busca en el archivo la cadena indicada (imitiendo el \0)
  41. */
  42. int buscar(char * ft, char * cadena, unsigned long * bytes){
  43.  
  44.    int longi = strlen(cadena);
  45.    if(longi < 1)
  46.        return -2;
  47.    int i=0;
  48.    int k=0;
  49.    while(i < *bytes){printf("Va bien con c=%x, k=%d\n", ft[i], k);
  50.        if(ft[i] == cadena[k]){
  51.            k++;
  52.            while(k < longi && ++i < *bytes && ft[i] == cadena[k])
  53.                k++;
  54.            if(k == longi)
  55.                return 0;
  56.            else if(i >= *bytes){
  57.                return -1;
  58.            }else{
  59.                k=0;
  60.            }
  61.        }else
  62.         ++i;
  63.  
  64.    }
  65.    return -1;
  66.  
  67. }
  68.  
  69. unsigned long flen(FILE *f){
  70.    unsigned long pos, len;
  71.  
  72.    pos = ftell(f);
  73.    fseek(f , 0 , SEEK_END);
  74.    len = ftell(f);
  75.    fseek(f , pos , SEEK_SET);
  76.  
  77.    return len;
  78. }
  79.  
  80. int cargar_fichero(FILE *f, char *contenido, unsigned long *nbytes){
  81.     if((contenido = (char*) malloc((*nbytes = flen(f)) * sizeof(char))) == NULL)
  82.        return 0;
  83.  
  84.  
  85.    return fread(contenido , sizeof(char) , (*nbytes/sizeof(char)) , f);
  86. }
En línea

do-while


Desconectado Desconectado

Mensajes: 1.276


¿Habra que sacarla de paseo?


Ver Perfil
Re: EOF en archivo antes de su verdadero final
« Respuesta #4 en: 1 Diciembre 2011, 18:31 pm »

¡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 Desconectado

Mensajes: 130


Ver Perfil
Re: EOF en archivo antes de su verdadero final
« Respuesta #5 en: 1 Diciembre 2011, 20:58 pm »

Jeje, esta tarde me he dado cuenta de eso...a partir de ahora seguiré la máxima de no tocarás código ajeno   ;D
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í:
Código
  1. FILE * fp = fopen(argv[i], "rb");
  2. char ** contenido;
  3. unsigned long bytes;
  4. cargar_fichero(f, contenido, &bytes);
y después a buscar le paso
Código
  1. 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 Desconectado

Mensajes: 1.639


Ver Perfil
Re: EOF en archivo antes de su verdadero final
« Respuesta #6 en: 1 Diciembre 2011, 23:54 pm »

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:
Código
  1. FILE *fp = fopen(argv[i], "rb");
  2. char *contenido;
  3. unsigned long bytes;
  4.  
  5. cargar_fichero(f, &contenido, &bytes);
  6.  
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 Desconectado

Mensajes: 1.276


¿Habra que sacarla de paseo?


Ver Perfil
Re: EOF en archivo antes de su verdadero final
« Respuesta #7 en: 2 Diciembre 2011, 11:59 am »

¡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:

Código
  1.  
  2. int cargar_fichero(FILE *f, char **contenido, unsigned logn *nbytes)
  3. {
  4.    unsigned long posicion;
  5.    int retorno;    
  6.  
  7.    if(!(*contenido = (char*) malloc((*nbytes = flen(f)) * sizeof(char))))
  8.        return 0;
  9.  
  10.    posicion = ftell(f);
  11.    fseek(f , 0 , SEEK_SET);
  12.  
  13.    retorno = fread(*contenido , (*nbytes) * sizeof(char) , 1 , f);
  14.  
  15.    fseek(f , posicion , SEEK_SET);
  16.  
  17.    return retorno;
  18. }
  19.  

¡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 Desconectado

Mensajes: 130


Ver Perfil
Re: EOF en archivo antes de su verdadero final
« Respuesta #8 en: 3 Diciembre 2011, 13:59 pm »

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.  :D
Un saludo!
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Juicio final cuanto antes « 1 2 ... 5 6 »
Foro Libre
@synthesize 58 31,406 Último mensaje 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,441 Último mensaje 10 Febrero 2011, 17:54 pm
por JMM13
Firefox 4 Beta 12 antes de la versión final
Noticias
wolfbcn 1 3,154 Último mensaje 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,464 Último mensaje 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,131 Último mensaje 30 Octubre 2015, 21:44 pm
por wolfbcn
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines