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

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Split en C
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Split en C  (Leído 2,500 veces)
Distorsion

Desconectado Desconectado

Mensajes: 238


15Hz ~ 20Hz


Ver Perfil
Split en C
« en: 27 Octubre 2012, 05:06 am »

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:

Código:
#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...


 ;D


En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Split en C
« Respuesta #1 en: 27 Octubre 2012, 19:58 pm »

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:
Código
  1. for(i = 0; i < tamtotal; i++) {
  2.   while((cadena[i + n] == buscada[n]) && (n < tam))
  3.      n++;
  4.   if (n == tam)
  5.      cantidad++;
  6.   n = 0;
  7. }
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:
Código
  1. 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 Desconectado

Mensajes: 238


15Hz ~ 20Hz


Ver Perfil
Re: Split en C
« Respuesta #2 en: 28 Octubre 2012, 00:58 am »

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 Desconectado

Mensajes: 238


15Hz ~ 20Hz


Ver Perfil
Re: Split en C
« Respuesta #3 en: 28 Octubre 2012, 02:23 am »

Listo, ya no hay cuelgues aleatorios.

 ;-)
En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Split en C
« Respuesta #4 en: 29 Octubre 2012, 03:18 am »

Otra forma, basada en aritmética de punteros y la función "strstr" (prototipo en <string.h>), es (falta la validación de errores):
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. char **separar(char const *cad, char const *sep, int *num_elem);
  6.  
  7. int main(void)
  8. {
  9.   char const *linea = "Holasss999 como estas 999freeze??? 999 :p999a999b999999c999d99aaaa999";
  10.   char **elem;
  11.   int num_elem;
  12.   int i;
  13.  
  14.   elem = separar(linea, "999", &num_elem);
  15.   for (i = 0; i < num_elem; i++)
  16.      printf("elem[%2d] == \"%s\"\n", i, elem[i]);
  17.  
  18.   for (i = 0; i < num_elem; i++)
  19.      free(elem[i]);
  20.   free(elem);
  21.  
  22.   return EXIT_SUCCESS;
  23. }
  24.  
  25. char **separar(char const *cad, char const *sep, int *num_elem)
  26. {
  27.   char **elem;
  28.   char *p;
  29.   int i;
  30.  
  31.   size_t nc_sep = strlen(sep);
  32.  
  33.   elem = malloc((strlen(cad) + nc_sep) / (nc_sep + 1) * sizeof *elem);
  34.  
  35.   for (i = 0; (p = strstr(cad, sep)) != NULL; cad = p + nc_sep){
  36.      if (p != cad){
  37.         elem[i] = malloc(p - cad + 1);
  38.         sprintf(elem[i], "%.*s", p - cad, cad);
  39.         i++;
  40.      }
  41.   }
  42.   if (*cad != '\0'){
  43.      elem[i] = malloc(strlen(cad) + 1);
  44.      strcpy(elem[i], cad);
  45.      i++;
  46.   }
  47.   *num_elem = i;
  48.  
  49.   return realloc(elem, i * sizeof *elem);
  50. }

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
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
No me va el split second :(
Juegos y Consolas
Hacker wifi 2 3,054 Último mensaje 2 Octubre 2010, 15:03 pm
por Hacker wifi
[C] Split
Programación C/C++
_*p 3 2,844 Último mensaje 19 Febrero 2011, 15:55 pm
por _*p
Split C++
Programación C/C++
|Apeiron| 0 1,887 Último mensaje 21 Noviembre 2011, 16:18 pm
por |Apeiron|
[SOLUCIONADO] Split
Programación Visual Basic
Miseryk 6 2,777 Último mensaje 21 Julio 2013, 09:38 am
por BlackZeroX
problema con split « 1 2 »
Java
alex_alex 12 4,769 Último mensaje 23 Mayo 2014, 22:35 pm
por alex_alex
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines