Función split para C
Publicado en C/C++, Recursos el 16 de May, 2008 por Fran.Hace poco programando en C, eché en falta una función split al estilo de Java, para dividir una cadena de caracteres en varias usando un carácter separador (ya sé que en el método de Java se pueden usar expresiones regulares, pero yo sólo buscaba la división a partir de un carácter).
Como no existe nada parecido, bueno strtok es algo parecido pero tiene muchos inconvenientes (para muchos es una función maldita), pues me decidí a programar una función que lo hiciera, viendo que parece que funciona bastante bien voy a dejar aquí el código por si a alguien le resultase útil o incluso quisiera mejorarla (es toda vuestra).
#include <stdlib.h>
/* split: Splits a string in parts delimited by a character. */
char **split (char *string, char sep) {
char **ret;
char *p = string;
int i = 0;
int nParts = 0;
int len = strlen (string);
ret = (char **) malloc (sizeof (char *));
if (ret == NULL)
return NULL;
ret[0] = NULL;
while (i < len) {
/* Jump the separator characters */
while ((p[i] == sep) && (i < len))
i++;
/* Find a non separator character */
if (i < len) {
char **tmp = (char **) realloc (ret,
(nParts + 2) * sizeof (char *));
if (tmp == NULL) {
free (ret);
return NULL;
}
ret = tmp;
tmp = NULL;
ret[nParts + 1] = NULL;
ret[nParts] = (char *) malloc (sizeof (char));
if (ret[nParts] == NULL) {
for (i = 0; i < nParts; i++)
free (ret[i]);
free (ret);
return NULL;
}
int j = 0;
for (i; ((p[i] != sep) && (i < len)); i++) {
ret[nParts][j] = p[i];
j++;
char *tmp2 = (char *) realloc (ret[nParts],
(j + 1) * sizeof (char));
if (ret[nParts] == NULL) {
for (i = 0; i < nParts; i++)
free (ret[i]);
free (ret);
return NULL;
}
ret[nParts] = tmp2;
tmp2 = NULL;
}
ret[nParts][j] = '\0';
nParts++;
}
}
return ret;
}
Como podéis ver la función devuelve un array de cadenas de caracteres cuya última posición es NULL, de modo que sólo tengáis que recorrer el array hasta encontrar NULL para conseguir las partes de la cadena dividida. Como es obvio, deberéis liberar la memoria del array devuelto una vez no lo vayáis a usar.
Si veis algún fallo decirlo y se corrige.
[...] es crear nuestra propia función split, o aun más fácil, copypastear la función desarrollada por 4 bits blog: #include [...]
# Función split en C 17 de May, 2008
Muchas gracias por la función, pero ¿tendriais la equivalente en c++ utilizando las librerias STL con el tipo string?
Un saludo Enrique
# enrique 19 de November, 2009
He hecho unos cambios para que funcione con strings y parece ser que lo hace, falta pulirlo con las caracteristicas de la clase string.
/* split: Splits a string in parts delimited by a character. */ char **split (string cadena, char sep) { char **ret; string p = cadena; int i = 0; int nParts = 0; int len = cadena.length(); ret = (char **) malloc (sizeof (char *)); if (ret == NULL) return NULL; ret[0] = NULL; while (i < len) { /* Jump the separator characters */ while ((p[i] == sep) && (i < len)) i++; /* Find a non separator character */ if (i < len) { char **tmp; tmp = (char **) realloc (ret, (nParts + 2) * sizeof (char *)); if (tmp == NULL) { free (ret); return NULL; } ret = tmp; tmp = NULL; ret[nParts + 1] = NULL; ret[nParts] = (char *) malloc (sizeof (char)); if (ret[nParts] == NULL) { for (i = 0; i < nParts; i++) free (ret[i]); free (ret); return NULL; } int j = 0; for (i; ((p[i] != sep) && (i < len)); i++) { ret[nParts][j] = p[i]; j++; char *tmp2; tmp2 = (char *) realloc (ret[nParts], (j + 1) * sizeof (char)); if (ret[nParts] == NULL) { for (i = 0; i < nParts; i++) free (ret[i]); free (ret); return NULL; } ret[nParts] = tmp2; tmp2 = NULL; } ret[nParts][j] = ''; nParts++; } } } } return ret; }# enrique 19 de November, 2009
Hola!
Me podrias resolver una duda?
En la primera función (en la de c), que es lo que le tengo que pasar?
no me sirve con pasarle un c, donde c es:
char * c;
c=fgets(palabra,105, fitxategi_ptr);
en c se me mete:
al hacer el printf,
printf(“%s\n”,c);
veo, / / //// / /i/ / / // / / / /_/0.00,149.20, 0.25,146.91, 0.50,144.75, 0.75,142.73/167.59/ 1.03/
Luego la llamada a la función la hago asi:
ret = split(&c,sep1);
Y no me funciona!! no se si estoy entendiendo mal la funcionalidad de la función.
Gracias!
# Karmele 23 de June, 2010
Karmele te confundes al llamar a la función
split, tienes que hacerlo así:ret = split (c, sep1);# Fran 23 de June, 2010
Gracias! Ahora si!!! Muchas gracias!!!
# karmele 23 de June, 2010
Otra cosilla, cuando visualizo ret, la i me la mete en ret[4], osea, en la quinta posición, cuando deberia encontrarse en la octava, y de ahí en adelante todos los caracteres están adelantados, sabes porque puede ser??
Gracias otra vez!
# Karmele 23 de June, 2010