substring en array char

Iniciado por soyloqbuskas, 21 Septiembre 2012, 02:45 AM

0 Miembros y 1 Visitante están viendo este tema.

soyloqbuskas

¡Buenas a todos!

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


#include <stdio.h>
#include <string.h>
int main(){

        char cadena[8]={'1','\0','3','4','5','6','\0','8'};
        char * busca="345";
        char* result="resultado";
        char cadena2[8];
        int i=1;
        int aux=1;
        printf("hola\n");
        for(i=1;i<9;i++){
                while((cadena[i]!='\0') && (i<9)){
                        cadena2[aux]=cadena[i];
                        aux++;
                }
                aux=1;
                result=strstr((char*)cadena2,busca);
                if(result!=NULL){ break;break;}
                printf("Resultado: %s\n",result);
        }
        //printf("Resultado: %s",result);
        return 0;
}


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.
"Si tienes 1 manzana y yo tengo otra manzana...
y las intercambiamos, ambos seguiremos teniendo 1 manzana.
Pero...si tu tienes 1 idea y yo tengo otra idea...
y las intercambiamos, ambos tendremos 2 ideas."


George Bernard Shaw

xiruko

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:

char* busca="345";
char* result="resultado";


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

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.

soyloqbuskas

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:
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.
"Si tienes 1 manzana y yo tengo otra manzana...
y las intercambiamos, ambos seguiremos teniendo 1 manzana.
Pero...si tu tienes 1 idea y yo tengo otra idea...
y las intercambiamos, ambos tendremos 2 ideas."


George Bernard Shaw

xiruko

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

#include <stdio.h>
#include <string.h>

int main() {

char *resultado=NULL, texto[]="hola que tal\nbien y tu\nbien gracias\n", buscar[]="bien";

resultado=strstr(texto, buscar);

if (resultado) printf("%s", resultado);
else printf("No se encontro.\n");

return 0;
}


y la salida es:


~$ 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 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?

soyloqbuskas

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:
texto[]="hola que tal\nbien y tu\ngracias\n¿Por que imprime el gracias y esto?"

Veras como lo imprime todo...
"Si tienes 1 manzana y yo tengo otra manzana...
y las intercambiamos, ambos seguiremos teniendo 1 manzana.
Pero...si tu tienes 1 idea y yo tengo otra idea...
y las intercambiamos, ambos tendremos 2 ideas."


George Bernard Shaw

Javier235

#include <stdio.h>
#include <string.h>

#define LENGTH 9

int main(){

char cadena[LENGTH]={'1','\0','3','4','5','6','\0','8','\0'};
char cadena2[LENGTH];
char *busca="345";
char *result=NULL;

int i, j=0;
for(i=0; i<LENGTH; i++) {
if(cadena[i] != '\0') {
cadena2[j] = cadena[i];
j++;
} else
j=0;

result=strstr(cadena2,busca);
if(result!=NULL) {
printf("Resultado: %s. i:%d\n",result, i);
j=0;
} else
printf("no se encontro nada. i:%d\n", i);
}

return 0;
}


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

xiruko

#6
CitarYa 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:

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:

int BuscarCadena(char* origen, char* buscar) {

int numeroApariciones=0, i=0, j;

while (origen[i]!='\0') {

for (j=0; j<strlen(buscar); j++)
if (origen[i+j]!=buscar[j]) break;

if (j==strlen(buscar)) numeroApariciones++;
                i++;
}

return numeroApariciones;
}


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

rir3760

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:
#include <string.h>

int num_reps(char const *cad, char const *sub)
{
   size_t nc_sub = strlen(sub);
   int i;
   char *p;
   
   for (i = 0; (p = strstr(cad, sub)) != NULL; i++)
      p += nc_sub;
   
   return i;
}


Un saludo
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

xiruko

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

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:

for (i=0; (p=strstr(p, sub)) != NULL; i++)

un saludo!

rir3760

Cita de: xiruko en 21 Septiembre 2012, 17:28 PMhe 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:
#include <string.h>

int num_reps(char const *p, char const *sub)
{
   size_t nc_sub = strlen(sub);
   int i;
   
   for (i = 0; (p = strstr(p, sub)) != NULL; i++)
      p += nc_sub;
   
   return i;
}


Un saludo (y gracias por la corrección)
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