• Sábado 27 de Abril de 2024, 01:48

Autor Tema:  Buscar string en un archivo, y obtener datos  (Leído 4289 veces)

emma1990

  • Nuevo Miembro
  • *
  • Mensajes: 4
    • Ver Perfil
Buscar string en un archivo, y obtener datos
« en: Lunes 21 de Marzo de 2011, 23:30 »
0
Hola!

No me vendría mal un poco de ayuda con un programa que estoy haciendo  :lol:

La historia consiste en que el programa abra un archivo de texto y busque una cadena, grabando lo que hay después de la cadena a otro archivo de texto.

Es decir, que si en el archivo input.txt hay esto: "blablabla nombre emma blablabla", obtenga un output.txt con el contenido "emma".

Soy bastante principiante en esto, pero sí sé abrir y cerrar archivos. Donde necesitaría ayuda es con lo demás

Alguna idea?

Gracias de antemano!   :D

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Buscar string en un archivo, y obtener datos
« Respuesta #1 en: Martes 22 de Marzo de 2011, 08:08 »
0
Lees el fichero línea por línea y usas strstr() para buscar una subcadena.

Saludos.

emma1990

  • Nuevo Miembro
  • *
  • Mensajes: 4
    • Ver Perfil
Re: Buscar string en un archivo, y obtener datos
« Respuesta #2 en: Martes 22 de Marzo de 2011, 14:10 »
0
Muchas gracias!
Voy a probar eso y te cuento
De todas formas, veo una pequeña dificultad... voy a saber leer el archivo y guardar cada línea a un string, y luego compararlo con mi string de búsqueda, pero.. cómo obtengo luego el dato que va después del string de búsqueda?

Gracias otra vez :D

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Buscar string en un archivo, y obtener datos
« Respuesta #3 en: Martes 22 de Marzo de 2011, 16:13 »
0
Mírate la documentación de strstr(), haz el favor  ^_^

emma1990

  • Nuevo Miembro
  • *
  • Mensajes: 4
    • Ver Perfil
Re: Buscar string en un archivo, y obtener datos
« Respuesta #4 en: Martes 22 de Marzo de 2011, 17:17 »
0
Cita de: "m0skit0"
Mírate la documentación de strstr(), haz el favor  ^_^
Vale, con strstr() llego a saber que en el string "enunlugardelamancha", el string "la" está en la posición 12. Ahora, cómo hago para copiar un substring de ese string, "mancha", con las posiciones 14-19 del string "enunlugardelamancha"? Ese es mi problema.

strcpy() no parece servirme, o al menos no sé como copiar el substring que me interese sabiendo la posición de inicio.

Saludos

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Buscar string en un archivo, y obtener datos
« Respuesta #5 en: Martes 22 de Marzo de 2011, 17:47 »
0
strcpy te sirve perfectamente, aunque yo siempre uso strncpy para evitar infernales bugs de desbordamientos de buffer (que además pueden comprometer la seguridad de tu programa).

Código: C
  1. unsigned int pos; // Suponemos que aquí tienes guardada la posición en que se encuentra la subcadena
  2. char* buscar; // Aquí la subcadena que buscas
  3. char* cadena; // Aquí la cadena completa
  4. char* resto; // Aquí es donde quieres almacenar el resto de la cadena
  5. // Recuerda reservar la memoria y liberarla para todos estos punteros ;)
  6. [...]
  7. char* aux = (char*) ((unsigned int)cadena + pos + strlen(buscar));
  8. strncpy(resto, aux, <tamaño de "resto">);
  9.  
Ojo que tienes que reservar suficiente memoria para que en resto pueda caber todo lo que venga después de la subcadena.

emma1990

  • Nuevo Miembro
  • *
  • Mensajes: 4
    • Ver Perfil
Re: Buscar string en un archivo, y obtener datos
« Respuesta #6 en: Miércoles 23 de Marzo de 2011, 10:59 »
0
Al final lo fui haciendo sin strcpy(). Qué te parece esto? A lo mejor es un poco chapuzas pero para lo que quiero es funcional   :P

Código: C
  1. FILE *pf;
  2. char cadena[100], linea[100], *ptr;
  3. pf = fopen("file.txt", "r");
  4. while (fgets(linea,100,pf) != NULL) {
  5.       fscanf(pf, "%s", &cadena);  
  6.       ptr=strstr(linea, "Ki");
  7. if (ptr!=0) printf("%c%c%c%c%cn", cadena[ptr-cadena+6], cadena[ptr-cadena+7], cadena[ptr-cadena+8], cadena[ptr-cadena+9], cadena[ptr-cadena+10]);
  8. }
  9. fclose(pf);
  10. }
  11.  

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Buscar string en un archivo, y obtener datos
« Respuesta #7 en: Miércoles 23 de Marzo de 2011, 11:39 »
0
Un poco no, es MUY chapuzas. ¿Y qué pasa si la línea tiene más de 5 caracteres después del marcador? ¿Y por qué empiezas en +6?

De todas formas, si lo que quieres es mostrar el resto de la cadena, te vale con

Código: C
  1. if (ptr != NULL)
  2. {
  3.     printf("%sn", (char*)((unsigned int)ptr + strlen("Ki")));
  4. }
  5.  
- No pongas las condiciones del if seguidas, es poco legible, y usa siempre { }, te ahorrarás futuros quebraderos de cabeza.
- Usa NULL, no 0 (tampoco hagas !ptr)
- No uses literales en el código, usa constantes (#define)

Además ese código es muy poco flexible. Intenta programar de manera que si te toca modificar el código (y créeme que lo vas a tener que modificar) no tengas que mover cielo y tierra.

Amilius

  • Miembro HIPER activo
  • ****
  • Mensajes: 665
    • Ver Perfil
Re: Buscar string en un archivo, y obtener datos
« Respuesta #8 en: Miércoles 23 de Marzo de 2011, 19:14 »
0
De acuerdo con todo, especialmente con adoptar un estilo definido de programación.

Aunque personalmente prefiero este tipo de comparaciones para verificar punteros no nulos:
Código: C++
  1.  
  2. if (ptr)
  3. {
  4. }
  5.  
  6.  

Y para los nulos prefiero usar el 0, ¿Para que escribir 4 letras y ocultar lo que en realidad es un puntero nulo?
Código: C++
  1.  
  2. if (0 == ptr)
  3. {
  4. }
  5.  
  6.  

Tampoco me hago problema con un if en una sóla linea siempre y cuando sea más rápido de leer. En casos extremadamente simples es más rápido leer esto:
Código: C++
  1.  
  2. if (0 == ptr) return;
  3.  
  4.  

que esto:
Código: C++
  1.  
  2. if (0 == ptr)
  3. {
  4.     return;
  5. }
  6.  
  7.  

haddad

  • Miembro activo
  • **
  • Mensajes: 33
    • Ver Perfil
Re: Buscar string en un archivo, y obtener datos
« Respuesta #9 en: Miércoles 23 de Marzo de 2011, 20:45 »
0
mmm creo  que quede un poco confundida en cuanto al orden de soluciones que planteaste
 
Cita de: "m0skit0"
printf("%sn", (char*)((unsigned int)ptr + strlen("Ki")));
eso es la solucion a?
Cita de: "m0skit0"
- No pongas las condiciones del if seguidas, es poco legible, y usa siempre { }, te ahorrarás futuros quebraderos de cabeza.
- Usa NULL, no 0 (tampoco hagas !ptr)
- No uses literales en el código, usa constantes (#define)

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Buscar string en un archivo, y obtener datos
« Respuesta #10 en: Jueves 24 de Marzo de 2011, 09:03 »
0
Cita de: "Amilius"
Y para los nulos prefiero usar el 0, ¿Para que escribir 4 letras y ocultar lo que en realidad es un puntero nulo?
Porque es menos portable. Estás asumiendo que el puntero nulo tiene el valor 0, algo que en otras arquitecturas distintas de Intel no tiene por qué ser así. Por algo existe la constante NULL, que es dependiente de la arquitectura.

Cita de: "Amilius"
Tampoco me hago problema con un if en una sóla linea siempre y cuando sea más rápido de leer.
A mí me parece menos legible por el simple hecho de tener distintas estructuras de ifs en todo el programa. Prefiero poner todos los ifs iguales, no veo porqué hay que poner unos ifs de una forma y otros de otra, no ayuda a la legibilidad en mi opinión. Pero vamos, es cuestión de formas y gustos.

Cita de: "haddad"
printf("%sn", (char*)((unsigned int)ptr + strlen("Ki")));
eso es la solucion a?
Es parecido a

Código: C
  1. printf("%c%c%c%c%cn", cadena[ptr-cadena+6], cadena[ptr-cadena+7], cadena[ptr-cadena+8], cadena[ptr-cadena+9], cadena[ptr-cadena+10]);
  2.  
pero bien hecho  :P  ^_^

Leber

  • Miembro activo
  • **
  • Mensajes: 65
    • Ver Perfil
Re: Buscar string en un archivo, y obtener datos
« Respuesta #11 en: Jueves 24 de Marzo de 2011, 11:05 »
0
Hola moskito, compilando esto:

Código: C
  1.  
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5.  
  6. int main(void)
  7. {
  8.     char line[] = "Hola que tal estas";
  9.     char *ptr;
  10.  
  11.             ptr = strstr (line, "que");
  12.             if(ptr != NULL) {
  13.                 printf("%sn", (char*) ((unsigned int)ptr + strlen("que")) );
  14.             }
  15.             return 0;
  16. }
  17.  

Me da un warning, y si lo ejecuto da segfault. Si entiendo bien, le estas diciendo "lo que contiene ptr" + "la longitud de que". Y por que se hace un cast a unsigned int? Siento tantas preguntas pero es que estaba leyendo esto ayer, y me pico la curiosidad.

Gracias de antemano

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Buscar string en un archivo, y obtener datos
« Respuesta #12 en: Jueves 24 de Marzo de 2011, 12:51 »
0
Perdona, lo había puesto sin probar.

Weno, acabo de ejecutar ese mismo programa y me funciona correctamente:

Código: Text
  1. root@bt:~# cat prueba.c
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5.  
  6. int main(void)
  7. {
  8.     char line[] = "Hola que tal estas";
  9.     char *ptr;
  10.  
  11.             ptr = strstr (line, "que");
  12.             if(ptr != NULL) {
  13.                 printf("%sn", (char*) ((unsigned int)ptr + strlen("que")) );
  14.             }
  15.             return 0;
  16. }
  17. root@bt:~# gcc -o prueba prueba.c
  18. root@bt:~# ./prueba
  19.  tal estas
  20. root@bt:~#
  21.  

Leber

  • Miembro activo
  • **
  • Mensajes: 65
    • Ver Perfil
Re: Buscar string en un archivo, y obtener datos
« Respuesta #13 en: Jueves 24 de Marzo de 2011, 13:01 »
0
Pues, acabo de copiar tu codigo, y no funciona. Mira:

Código: C
  1. test@sistemes-oscar:~/c$ cat prueba.c
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5.  
  6. int main(void)
  7. {
  8.     char line[] = "Hola que tal estas";
  9.     char *ptr;
  10.  
  11.             ptr = strstr (line, "que");
  12.             if(ptr != NULL) {
  13.                 printf("%sn", (char*) ((unsigned int)ptr + strlen("que")) );
  14.             }
  15.             return 0;
  16. }
  17. test@sistemes-oscar:~/c$ gcc -o prueba prueba.c
  18. prueba.c: In function ‘main’:
  19. prueba.c:12: warning: cast from pointer to integer of different size
  20. test@sistemes-oscar:~/c$ ./prueba
  21. Segmentation fault
  22. test@sistemes-oscar:~/c$
  23.  

Me resulta bastante extraño.
Lo mismo, si lo hago en SO de 32 bits, funciona:

Código: C
  1. test@sistemes-test:~$ cat proba.c
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>                                                                                                                                                                  
  5.                                                                                                                                                                                      
  6. int main(void)                                                                                                                                                                        
  7. {                                                                                                                                                                                    
  8.     char line[] = "Hola que tal estas";                                                                                                                                              
  9.     char *ptr;                                                                                                                                                                        
  10.                                                                                                                                                                                      
  11.             ptr = strstr (line, "que");                                                                                                                                              
  12.             if(ptr != NULL) {
  13.                 printf("%sn", (char*) ((unsigned int)ptr + strlen("que")) );
  14.             }
  15.             return 0;
  16. }
  17.  
  18. test@sistemes-test:~$ ./proba
  19.  tal estas
  20. test@sistemes-test:~$
  21.  

En mi maquina, mi SO es de 64 bits, y no funciona, en esta ultima es de 32 bits y funciona. Ambas maquinas tienen la misma version del gcc 4.4.3.
No se ver muy claro por que en 32 si y en 64 no, lo unico que me viene a la cabeza es que los punteros en 64 bits ocupan 8 bytes en lugar de 4 como ocurre en 32, pero... esto no debería afectar en este codigo, no?

Gracias

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Buscar string en un archivo, y obtener datos
« Respuesta #14 en: Jueves 24 de Marzo de 2011, 13:36 »
0
Bueno, esto lo malo que tiene C, que es poco portable si te pones a hacer malabares con punteros y casts.

El problema radica efectivamente como dices en el tamaño del puntero y en el uso de unsigned int, que si no recuerdo mal tiene el mismo tamaño en 32 que en 64 bits, de ahí el warning del compilador de que se están sumando dos tipos de tamaños diferentes (warning: cast from pointer to integer of different size) y por tanto pierdes posiblemente medio puntero, con lo que la dirección a la que apunta ya no tiene nada que ver, de ahí la violación de segmento.

Creo que si pones unsigned long long te debería funcionar sin problemas (no puedo probarlo porque no tengo máquina de 64 bits).

Saludos

Leber

  • Miembro activo
  • **
  • Mensajes: 65
    • Ver Perfil
Re: Buscar string en un archivo, y obtener datos
« Respuesta #15 en: Jueves 24 de Marzo de 2011, 13:51 »
0
Efectivamente, 4 bytes se pierden con solo unsigned int.  Aunque basta con ponert unsigned long int:


Código: C
  1. int main(void)
  2. {
  3.     char line[] = "Hola que tal estas";
  4.     char *ptr;
  5.  
  6.             printf("Size int-> %ldn", sizeof(unsigned int));
  7.             printf("Size int-> %ldn", sizeof(unsigned long int));
  8.  
  9.             ptr = strstr (line, "que");
  10.             if(ptr != NULL) {
  11.                 printf("%sn", (char*) ((unsigned long int)ptr + strlen("que")) );
  12.             }
  13.             return 0;
  14. }
  15.  
  16.  
  17. test@test:~/c$ ./prueba
  18. Size int-> 4
  19. Size int-> 8
  20.  tal estas
  21.  


Igualmente, tengo otra duda, y es sobre:

Código: C
  1. (char*) ((unsigned long int)ptr + strlen("que"))
  2.  

Sobretodo esta parte:

Código: C
  1. (unsigned long int)ptr
  2.  
. Estas casteando la direccion de memoria, y le sumas 3, que es la longitud de la cadena.

Entonces, si la direccion de ptr empieza en "0x7fffd1573a20" le sumas 3 quedando: "0x7fffd1573a23"  

Es correcto, o me estoy liando?

Saludos, y gracias por las respuestas =)

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Buscar string en un archivo, y obtener datos
« Respuesta #16 en: Jueves 24 de Marzo de 2011, 14:21 »
0
Cita de: "Leber"
Aunque basta con ponert unsigned long int
Ah, ok. En 32 bits y según mi experiencia sizeof(long) = sizeof(int)
Código: C
  1. #include <stdio.h>
  2.  
  3. int main(void)
  4. {
  5.     printf("%d %dn", sizeof(int), sizeof(long));
  6.     return 0;
  7. }
  8.  
de ahí que dijera long long  ^_^

Cita de: "Leber"
Estas casteando la direccion de memoria, y le sumas 3, que es la longitud de la cadena.
Entonces, si la direccion de ptr empieza en "0x7fffd1573a20" le sumas 3 quedando: "0x7fffd1573a23"
Es correcto, o me estoy liando?
Exacto. Hago el cast para que el compilador entienda que no me he equivocado, que efectivamente quiero que a un puntero le sume un entero, pero que luego lo siga considerando un puntero. Y le sumo la longitud de la cadena para posicionarme al final de la cadena que se ha encontrado con strstr().

Ojo y repito que esto sólo funciona si quiero el resto de la cadena (desde la posición X hasta final de cadena). De otro modo que no sea hasta el final de la cadena habría que hacer un memcpy/strncpy en un buffer y añadirle el terminador de cadena antes de poder mostrarlo con printf (o cualquier otra función de manejo de cadenas).

Leber

  • Miembro activo
  • **
  • Mensajes: 65
    • Ver Perfil
Re: Buscar string en un archivo, y obtener datos
« Respuesta #17 en: Jueves 24 de Marzo de 2011, 16:11 »
0
Hola m0skito.

Si, entiendo que ese es el funcionamiento, que lo que quieres es:

Teniendo una cadena tal que asi: "hola que tal", y que strstr te devuelva un puntero a "que tal" (porque has buscado la primera aparicion de que), lo que le estas diciendo es:

Muestrame lo que sigue a partir de la posicion, p.e: 0x7fffd1573a23, (teniendo en cuenta que ptr apunte a 0x7fffd1573a20). Entonces recibes a partir de 0x7fffd1573a23 hasta final de linea.

Gracias por tu ayuda, me ha quedado bastante claro, y es algo que siempre he tenido algo así así, sabian lo que eran los punteros, pero no los habia manipulado de esta manera, no habia entendido nunca demasiado bien el desplazamiento que podias hacer a traves de la memoria, como ahora.

Saludos y gracias

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Buscar string en un archivo, y obtener datos
« Respuesta #18 en: Jueves 24 de Marzo de 2011, 16:34 »
0
Cita de: "Leber"
Entonces recibes a partir de 0x7fffd1573a23 hasta final de linea.
Bueno, para seguir hablando de posiciones de memoria, que muestre los caracteres desde 0x7fffd1573a23 hasta que encuentre un byte (o carácter) nulo.

No hay de qué, estamos aquí para compartir lo que sabemos, así que ya sabes, ahora te toca a ti compartir  ;)  :comp:

Leber

  • Miembro activo
  • **
  • Mensajes: 65
    • Ver Perfil
Re: Buscar string en un archivo, y obtener datos
« Respuesta #19 en: Jueves 24 de Marzo de 2011, 17:04 »
0
Cita de: "m0skit0"
No hay de qué, estamos aquí para compartir lo que sabemos, así que ya sabes, ahora te toca a ti compartir  ;)  :comp:

Intentaremos que así sea =)