Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: soyloqbuskas en 21 Septiembre 2012, 02:45 am



Título: substring en array char
Publicado por: soyloqbuskas en 21 Septiembre 2012, 02:45 am
¡Buenas a todos!

Tengo un problemilla con una funcion de C en linux. EL codigo es el siguiente:

Código
  1. #include <stdio.h>
  2. #include <string.h>
  3. int main(){
  4.  
  5.        char cadena[8]={'1','\0','3','4','5','6','\0','8'};
  6.        char * busca="345";
  7.        char* result="resultado";
  8.        char cadena2[8];
  9.        int i=1;
  10.        int aux=1;
  11.        printf("hola\n");
  12.        for(i=1;i<9;i++){
  13.                while((cadena[i]!='\0') && (i<9)){
  14.                        cadena2[aux]=cadena[i];
  15.                        aux++;
  16.                }
  17.                aux=1;
  18.                result=strstr((char*)cadena2,busca);
  19.                if(result!=NULL){ break;break;}
  20.                printf("Resultado: %s\n",result);
  21.        }
  22.        //printf("Resultado: %s",result);
  23.        return 0;
  24. }
  25.  

La idea de este codigo es la siguiente:
Tengo un char [] con caracteres y entre estos caracteres hay varios \0. Lo que quiero es trocear el char[] usando como caracter separador el \0, para luego buscar en el interior de cada trozo de cadena con strstr()

En el array char he puesto los \0 porque creo que es el caracter del salto de linea.

¿Alguien puede hecharme un cable?

Gracias, un saludo.


Título: Re: substring en array char
Publicado por: xiruko en 21 Septiembre 2012, 03:03 am
el caracter '\0' es el caracter NULL, el cual en C se usa entre otras cosas para indicar el fin de una cadena. el caracter de salto de linea que tu buscas es el '\n' o 10 en ascii. ademas, los arreglos siempre empiezan en la posicion 0, y tu recorres las cadenas empezando por la posicion 1.

luego declarar una cadena asi:

Código
  1. char* busca="345";
  2. char* result="resultado";

realmente no se si se puede. nunca lo he hecho ya que para declarar una cadena inicializada se suele hacer asi:

Código
  1. char busca[]="345";

que ya el solo declara un arreglo de 4 posiciones (3 para los caracteres mas el NULL al final). si tuviera que apostar diria que no se puede hacer como lo has hecho tu, ya que tu ahi estas declarando un puntero pero en ningun momento declaras el espacio necesario para almacenar la cadena "345". pero no lo se seguro y ahora me da algo de pereza probarlo... a ver si alguien mas comenta. sino, escribiendo los errores que te da el compilador podriamos saberlo.

para acabar, "result" es un puntero que te indicara si la funcion strstr() salio bien o no. por lo que no entiendo porque lo inicializas (en el caso de que se pueda hacerlo asi) a "resultado". lo que tendrias que hacer, al igual que con todos los punteros, es inicializarlo a NULL, y luego ya operaras con el.


Título: Re: substring en array char
Publicado por: soyloqbuskas en 21 Septiembre 2012, 03:26 am
ufffffffff la verdad es que lo he hecho bastante mal......porque para empezar mi funcion no recibe los parametros que he dicho...xD y he estado intentando programar una funcion que luego no me iba a servir (cagada).

De todas formas xiruko ese codigo esta muy machacado, como no me salido he probado todo lo que se me ha ocurrido para ver si me salia....y por eso esta asi de mal...

De todas formas esta declaracion:
Código
  1. char * cadena="loquesea"
Es correcta, aun que no es una buena practica de programacion...

Bueno, voy a replantear mi problema correctamente.

mi funcion recibe un unsigned char*, esta variable tiene un monton de saltos de linea. Quiero buscar un string en su interior. El problema es que strstr() busca hasta que llega al primer salto de linea, y si el string que busco esta despues del primer salto de linea pues no lo va a encontrar....Por ello debo primero trocear el contenido de mi variable unsigned char* usando como separador el salto de linea y luego utilizar el strstr() en cada uno de esos trozos.


Título: Re: substring en array char
Publicado por: xiruko en 21 Septiembre 2012, 04:26 am
Citar
mi funcion recibe un unsigned char*, esta variable tiene un monton de saltos de linea. Quiero buscar un string en su interior. El problema es que strstr() busca hasta que llega al primer salto de linea, y si el string que busco esta despues del primer salto de linea pues no lo va a encontrar....Por ello debo primero trocear el contenido de mi variable unsigned char* usando como separador el salto de linea y luego utilizar el strstr() en cada uno de esos trozos.

bueno yo acabo de hacer este sencillo ejemplo:

Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int main() {
  5.  
  6. char *resultado=NULL, texto[]="hola que tal\nbien y tu\nbien gracias\n", buscar[]="bien";
  7.  
  8. resultado=strstr(texto, buscar);
  9.  
  10. if (resultado) printf("%s", resultado);
  11. else printf("No se encontro.\n");
  12.  
  13. return 0;
  14. }

y la salida es:

Código:
~$ gcc prueba.c -o prueba
~$ ./prueba
bien y tu
bien gracias
~$

que segun la definicion de la funcion http://c.conclase.net/librerias/?ansifun=strstr (http://c.conclase.net/librerias/?ansifun=strstr) esto es exactamente lo que tiene que hacer. no dice nada de que busca hasta encontrar un espacio, al contrario, dice que busca hasta encontrar el caracter nulo de fin de cadena. en este ejemplo que te he puesto, "resultado" apunta a la primera coincidencia que se encuentra, que es el primer "bien", y tendra el valor de toda la cadena hasta el caracter NULL del final.

es esto lo que buscas hacer con tu funcion o es otra cosa? lo que pretendes es encontrar una sola palabra o frase en concreto dentro de la otra?


Título: Re: substring en array char
Publicado por: soyloqbuskas en 21 Septiembre 2012, 05:09 am
Ya pero si lees bien lo que pone, dice que localiza la primera aparicion solamente, a ti te lo muestra las 2 veces porque imprime hasta el caracter nulo. De hecho si pruebas a cambiar tu variable texto por esta:
Código
  1. texto[]="hola que tal\nbien y tu\ngracias\n¿Por que imprime el gracias y esto?"

Veras como lo imprime todo...


Título: Re: substring en array char
Publicado por: Javier235 en 21 Septiembre 2012, 07:34 am
Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. #define LENGTH 9
  5.  
  6. int main(){
  7.  
  8. char cadena[LENGTH]={'1','\0','3','4','5','6','\0','8','\0'};
  9. char cadena2[LENGTH];
  10. char *busca="345";
  11. char *result=NULL;
  12.  
  13. int i, j=0;
  14. for(i=0; i<LENGTH; i++) {
  15. if(cadena[i] != '\0') {
  16. cadena2[j] = cadena[i];
  17. j++;
  18. } else
  19. j=0;
  20.  
  21. result=strstr(cadena2,busca);
  22. if(result!=NULL) {
  23. printf("Resultado: %s. i:%d\n",result, i);
  24. j=0;
  25. } else
  26. printf("no se encontro nada. i:%d\n", i);
  27. }
  28.  
  29. return 0;
  30. }
  31.  

Fijate si te sirve. En teoría tendría que encontrar "345" una sola vez... según lo que vos querés hacer.


Título: Re: substring en array char
Publicado por: xiruko en 21 Septiembre 2012, 14:32 pm
Citar
Ya pero si lees bien lo que pone, dice que localiza la primera aparicion solamente, a ti te lo muestra las 2 veces porque imprime hasta el caracter nulo. De hecho si pruebas a cambiar tu variable texto por esta:

Código
  1. texto[]="hola que tal\nbien y tu\ngracias\n¿Por que imprime el gracias y esto?"

Veras como lo imprime todo...

no imprimira todo, imprimira desde el primer "bien" hasta el final de la cadena, que es exactamente lo que tiene que hacer esa funcion. tu lo que quieres hacer es que solo te imprima la palabra "bien"? quiero decir, tu buscas algo, y si lo encuentra, que te diga que si se encuentra en el texto y donde?

edito: he hecho una funcion para que te diga el numero de veces que una cadena esta en otra. no se si es exactamente lo que buscas, a ver si comentas y lo explicas un poco mejor. espero que te sirva:

Código
  1. int BuscarCadena(char* origen, char* buscar) {
  2.  
  3. int numeroApariciones=0, i=0, j;
  4.  
  5. while (origen[i]!='\0') {
  6.  
  7. for (j=0; j<strlen(buscar); j++)
  8. if (origen[i+j]!=buscar[j]) break;
  9.  
  10. if (j==strlen(buscar)) numeroApariciones++;
  11.                i++;
  12. }
  13.  
  14. return numeroApariciones;
  15. }

edito: para corregir un error en la condicion del while.


Título: Re: substring en array char
Publicado por: rir3760 en 21 Septiembre 2012, 17:13 pm
Hay un error en esa función: el utilizar el operador "++" en la condición tiene como efecto que la variable "i", en el cuerpo del bucle, sea el indice del siguiente carácter.


Otra forma es utilizando la función "strstr", por ejemplo:
Código
  1. #include <string.h>
  2.  
  3. int num_reps(char const *cad, char const *sub)
  4. {
  5.   size_t nc_sub = strlen(sub);
  6.   int i;
  7.   char *p;
  8.  
  9.   for (i = 0; (p = strstr(cad, sub)) != NULL; i++)
  10.      p += nc_sub;
  11.  
  12.   return i;
  13. }

Un saludo


Título: Re: substring en array char
Publicado por: xiruko en 21 Septiembre 2012, 17:28 pm
Citar
Hay un error en esa función: el utilizar el operador "++" en la condición tiene como efecto que la variable "i", en el cuerpo del bucle, sea el indice del siguiente carácter.

cierto, lo escribi y ejecute y funcionaba, pero claro funcionaba porque la palabra a buscar no estaba justo al inicio de la frase. gracias por el dato, ahora mismo lo corrijo.

luego he probado tu funcion y no me iba, y creo que es porque aunque aumentes el puntero sumandole la longitud de la cadena, luego a la funcion strstr() le vuelves a pasar la cadena original "cad", por lo que el programa entra en un bucle infinito. haciendo esto si que funciona:

Código
  1. char* p=cad;

y luego en la condicion del for le pasas el puntero a strstr() para aumentarlo dentro si encuentra la cadena a buscar:

Código
  1. for (i=0; (p=strstr(p, sub)) != NULL; i++)

un saludo!


Título: Re: substring en array char
Publicado por: rir3760 en 21 Septiembre 2012, 17:57 pm
he probado tu funcion y no me iba, y creo que es porque aunque aumentes el puntero sumandole la longitud de la cadena, luego a la funcion strstr() le vuelves a pasar la cadena original "cad", por lo que el programa entra en un bucle infinito.
Ouch! Cierto, eso pasa por verificar los programas "en la cabeza". La corrección es como indicas.

Pensándolo un poco no es necesaria una variable local (el puntero "p") ya que se puede utilizar el primer parámetro acortando la función a:
Código
  1. #include <string.h>
  2.  
  3. int num_reps(char const *p, char const *sub)
  4. {
  5.   size_t nc_sub = strlen(sub);
  6.   int i;
  7.  
  8.   for (i = 0; (p = strstr(p, sub)) != NULL; i++)
  9.      p += nc_sub;
  10.  
  11.   return i;
  12. }
  13.  

Un saludo (y gracias por la corrección)


Título: Re: substring en array char
Publicado por: xiruko en 21 Septiembre 2012, 18:57 pm
vaya pensaba que haciendo eso alterabas la cadena original haciendo que el puntero ya no apuntase al principio de la cadena despues de la funcion, pero lo he ejecutado y funciona correctamente. supongo que cuando le pasas un puntero a una funcion, este es una copia y no el original.

pensaba que esto ya lo tenia claro pero siempre se aprende algo nuevo xD

un saludo!


Título: Re: substring en array char
Publicado por: soyloqbuskas en 21 Septiembre 2012, 19:15 pm
¡Buenas a todos!

Xiruko, andamos cerca pero no damos en el clavo! jaja a ver si nos sale :-)

Citar
no imprimira todo, imprimira desde el primer "bien" hasta el final de la cadena

Efectivamente, pero yo no quiero que me imprima hasta el final de la cadena quiero que imprima desde que encuentra la cadena hasta el primer \n.

Ejemplo:

Citar
unsigned char* cadena="hola\nque tal\nbien\n"
Resultado:
que tal
/******************************************/
unsigned char* cadena="hola\nque tal\nbien\n¿que haces hoy?"
Resultado:
que tal
que haces hoy?

Para conseguir estos resultados 1º hacer un bucle que me trocee la cadena usando como delimitador el \n y me lo guarde en una variable y luego a esa variable hacer el strstr().

Gracias a todos por las respuestas, un saludo.


Título: Re: substring en array char
Publicado por: soyloqbuskas en 21 Septiembre 2012, 19:51 pm
¡AL FIN! jajaja

Ya tengo el codigo, no me puedo creer que me haya atascado tanto en un funcion tan simple jaja

Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int main(){
  5.  
  6.        unsigned char * cadena="aaaa\nbbbb\nccccc1\ndddddd\nccccc2\nffff\nccccc3";
  7.  
  8.        char* buscar="ccc";
  9.  
  10.        char aux[50]="";  //array donde llenaremos con la cadena troceada
  11.        char* result="";
  12.        int i=0;
  13.        int j=0;
  14.        int longitud=strlen((char*)cadena);
  15.  
  16.        for(i=0;i<longitud;i++){
  17.                if(cadena[i]!='\n'){  // si no hay \n  sigue llenando aux.
  18.                        aux[j]=cadena[i];
  19.                        j++;
  20.                }
  21.                else{   // hay un \n, busca en el interior de aux
  22.                        aux[j]='\0';
  23.                        result=strstr((char*)aux,buscar);
  24.                        if(result){
  25.                               printf("Encontrado: %s\n",result);  //si encuentras imprime
  26.                               // return 0;  Si quieres que solo imprima el primero descomenta la linea.
  27.                        }
  28.                        j=0;
  29.                }
  30.        }
  31.  
  32.        //ahora hay que imprimir el ultimo porque el bucle solo imprime hasta que encuentra un \n
  33.        result=strstr((char*)aux,buscar);
  34.        if(result) printf("Encontrado: %s\n",result);
  35.  
  36.        return 0;
  37. }
  38.  

Muchas gracias a todos por vuestra ayuda, un saludo.


Título: Re: substring en array char
Publicado por: rir3760 en 22 Septiembre 2012, 00:33 am
No es necesario copiar la cadena en un array auxiliar. En su lugar puedes utilizar "strstr" para buscar la subcadena, si se encuentra utilizas "strchr" para buscar el carácter '\n' después de esta.

Tu programa con esas modificaciones:
Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int main(void)
  5. {
  6.   char *cadena = "aaaa\nbbbb\nccccc1\ndddddd\nccccc2\nffff\nccccc3";
  7.   char *buscar = "ccc";
  8.   size_t nc_buscar = strlen(buscar);
  9.   char *p;
  10.   char *q;
  11.  
  12.   p = cadena;
  13.   while ((p = strstr(p, buscar)) != NULL){
  14.      if ((q = strchr(p + nc_buscar, '\n')) != NULL){
  15.         printf("%.*s\n", q - p, p);
  16.         p = q + 1;
  17.      }else {
  18.         printf("%s\n", p);
  19.         break;
  20.      }
  21.   }
  22.  
  23.   return 0;
  24. }

Un saludo