Autor
|
Tema: Split en C (Leído 2,763 veces)
|
Distorsion
Desconectado
Mensajes: 238
15Hz ~ 20Hz
|
Buenas, He estado buscando información y lo que más me ha convencido es este código de Ferchu, que es justo lo que necesito, separar por una palabra, no solo un carácter: #include <stdio.h> #include <windows.h> int separar(char ***vector, char *cadena, char *buscada); int main(int argc, char *argv[]) { char frase[]="Holasss999 como estas 999freeze??? 999 :p999a999b999999c999d99aaaa999"; char **palabras; int cant,i; cant = separar(&palabras,frase,"999"); for(i=0;palabras[i];i++)printf("%s\n",palabras[i]); system("PAUSE"); return EXIT_SUCCESS; } int separar(char ***vector, char *cadena, char *buscada){ char **palabras; int tam,i,iant=0,n=0,cantidad=1; int tamtotal,tamfrase; tamtotal=strlen(cadena); tam=strlen(buscada); // recorro primero una vez para contar las partes, para no complicarla con realloc. for(i=0;i<tamtotal;i++){ while((cadena[i+n]==buscada[n])&&(n<tam))n++; if(n==tam)cantidad++; n=0; } palabras=(char **)malloc(cantidad * sizeof(char **)); cantidad=0; for(i=0;i<tamtotal;i++){ while((cadena[i+n]==buscada[n])&&(n<tam))n++; if(n==tam){ tamfrase=i-iant; palabras[cantidad]=(char*)malloc(tamfrase); memcpy(palabras[cantidad],&cadena[iant],tamfrase); palabras[cantidad][i-iant]=0; iant=i+tam; cantidad++; i=i+tam; } n=0; } tamfrase=i-iant; palabras[cantidad]=(char*)malloc(tamfrase); memcpy(palabras[cantidad],&cadena[iant],tamfrase); palabras[cantidad][tamfrase]=0; palabras[cantidad+1]=0; *vector=palabras; return cantidad; } El problema es que al usar la función Separar me da cuelgues aleatorios. Los cuelgues me los da al usarla para filtrar conexiones html, buscando cadenas en el protocolo. La verdad no se porque, si alguien le ve el fallo...
|
|
|
En línea
|
|
|
|
rir3760
Desconectado
Mensajes: 1.639
|
Los problemas con la función son tres: * El primero ocurre al contar las instancias del separador, supongamos que este es "999" y la cadena a tasajear inicia con "99999". En base a ello el primer bucle de la función: for(i = 0; i < tamtotal; i++) { while((cadena[i + n] == buscada[n]) && (n < tam)) n++; if (n == tam) cantidad++; n = 0; }
Contara tres instancias del separador cuando solo hay una, eso debido a que avanza por la cadena carácter por carácter. * El segundo es no verificar si el valor de la variable: tamfrase = i - iant;
Es igual a cero (eso ocurre si hay dos separadores lado a lado), a continuación se trata de reservar memoria con "malloc" y no es valida una reserva de cero. * El tercero, cuando se hace la reserva de memoria se debe reservar un carácter adicional para el indicador de fin de cadena (el '\0'). No es difícil realizar los cambios, lo podrías tomar como un ejercicio. 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
|
|
|
Distorsion
Desconectado
Mensajes: 238
15Hz ~ 20Hz
|
Mil gracias macho. Los dos primeros los descarto, porque al usar de separador una palabra, es imposible en el contexto donde lo ejecuto que hayan dos seguidas. Intentare reservar un carácter extra y comento el resultado.
|
|
|
En línea
|
|
|
|
Distorsion
Desconectado
Mensajes: 238
15Hz ~ 20Hz
|
Listo, ya no hay cuelgues aleatorios.
|
|
|
En línea
|
|
|
|
rir3760
Desconectado
Mensajes: 1.639
|
Otra forma, basada en aritmética de punteros y la función "strstr" (prototipo en <string.h>), es (falta la validación de errores): #include <stdio.h> #include <stdlib.h> #include <string.h> char **separar(char const *cad, char const *sep, int *num_elem); int main(void) { char const *linea = "Holasss999 como estas 999freeze??? 999 :p999a999b999999c999d99aaaa999"; char **elem; int num_elem; int i; elem = separar(linea, "999", &num_elem); for (i = 0; i < num_elem; i++) printf("elem[%2d] == \"%s\"\n", i , elem [i ]); for (i = 0; i < num_elem; i++) return EXIT_SUCCESS; } char **separar(char const *cad, char const *sep, int *num_elem) { char **elem; char *p; int i; elem = malloc((strlen(cad ) + nc_sep ) / (nc_sep + 1) * sizeof *elem ); for (i = 0; (p = strstr(cad , sep )) != NULL ; cad = p + nc_sep ){ if (p != cad){ elem [i ] = malloc(p - cad + 1); sprintf(elem [i ], "%.*s", p - cad , cad ); i++; } } if (*cad != '\0'){ i++; } *num_elem = i; return realloc(elem , i * sizeof *elem ); }
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
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
No me va el split second :(
Juegos y Consolas
|
Hacker wifi
|
2
|
3,235
|
2 Octubre 2010, 15:03 pm
por Hacker wifi
|
|
|
[C] Split
Programación C/C++
|
_*p
|
3
|
3,054
|
19 Febrero 2011, 15:55 pm
por _*p
|
|
|
Split C++
Programación C/C++
|
|Apeiron|
|
0
|
2,048
|
21 Noviembre 2011, 16:18 pm
por |Apeiron|
|
|
|
[SOLUCIONADO] Split
Programación Visual Basic
|
Miseryk
|
6
|
3,037
|
21 Julio 2013, 09:38 am
por BlackZeroX
|
|
|
problema con split
« 1 2 »
Java
|
alex_alex
|
12
|
5,185
|
23 Mayo 2014, 22:35 pm
por alex_alex
|
|