Publi

Separar palabras de una cadena en C [ método dinámico con puntero triple ]

photo-1444228250525-3d441b642d12
Hace un mes o así publiqué un método para extraer las palabras de una cadena en un Array, ahora traigo un nuevo fragmento de código cuya misión es no estar tan limitado, y no tener que decir con antelación y con ello no tener que reservar memoria precipitadamente.

Dejo dos códigos fuente, en el primero, la reserva de memoria para almacenaje de información es palabra por palabra, es decir, me llega una palabra reservo memoria, me llega otra, amplio en 1 elemento la memoria reservada y así hasta recibir todas (incluyo el código para probar la función):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/**
******************************************************************
* @brief Extrae palabras de una cadena y las coloca en un puntero
*        doble E/S (triple, por tanto).
*
* @param orig     Cadena inicial
* @param delim    Las palabras vendrán delimitadas por uno de los
*                 caracteres de esta cadena
* @param args     El primer puntero hace reservas de las direcciones
*                 donde se colocarán los fragmentos de cadena.
*
* @return Número de palabras extraídas. (max_args+1) si en la
*         cadena hay más de max_args palabras.
*
******************************************************************/

int extrae_argumentos_dd(char *orig, char *delim, char ***args)
{
char *tmp;
int num=0;
/* Reservamos memoria para copiar la cadena ... pero la memoria justa */
char *str= malloc(strlen(orig)+1);
char **aargs;

strcpy(str, orig);

aargs=malloc(sizeof(char**));

tmp=strtok(str, delim);
do
{
aargs[num]=malloc(sizeof(char*));

/*       strcpy(aargs[num], tmp); */
aargs[num]=tmp;
num++;

/* Reservamos memoria para una palabra más */
aargs=realloc(aargs, sizeof(char**)*(num+1));

/* Extraemos la siguiente palabra */
tmp=strtok(NULL, delim);
} while (tmp!=NULL);

*args=aargs;
return num;
}

int main()
{
char cadena[]="Bienvenido al blog Poesía Binaria. Esto es una prueba del extractor de argumentos con puntero triple";
char **args4;
int i;
int nargs;

nargs=extrae_argumentos_dd(cadena, " ", &amp;args4);

printf("CADENA: %s\n", cadena);
for (i=0; i<nargs;i++)
printf("Palabra %d: "%s"\n", i, args4[i]);
}

En el segundo ejemplo, la memoria se reserva por grupos, es decir, 10 punteros ocupan muy poco, así que en vez de estar molestando siempre al sistema pidiendo memoria poco a poco, voy a pedir de 10 en 10 punteros (configurable vía DEFAULT_EXTRAE_RESERVA):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MAX_ARGS 90
#define MAX_CADENA 100
#define DEFAULT_EXTRAE_RESERVA 5
/**
******************************************************************
* @brief Extrae palabras de una cadena y las coloca en un puntero
*        doble E/S.
*
* @param orig     Cadena inicial
* @param delim    Las palabras vendrán delimitadas por uno de los
*                 caracteres de esta cadena
* @param args     El primer puntero hace reservas de las direcciones
*                 donde se colocarán los fragmentos de cadena.
*
* @return Número de palabras extraídas. (max_args+1) si en la
*         cadena hay más de max_args palabras.
*
******************************************************************/

int extrae_argumentos_ddg(char *orig, char *delim, char ***args)
{
char *tmp;
int num=0;
/* Reservamos memoria para copiar la candena ... pero la memoria justa */
char *str= malloc(strlen(orig)+1);
char **aargs;
int reserv = DEFAULT_EXTRAE_RESERVA;
strcpy(str, orig);

aargs=malloc(sizeof(char**)*reserv);

tmp=strtok(str, delim);
do
{
if (num==reserv)
{
reserv=reserv+DEFAULT_EXTRAE_RESERVA;
aargs=realloc(aargs, reserv*sizeof(char**));
}

aargs[num]=malloc(sizeof(char*));

aargs[num]=tmp;
num++;

/* Extraemos la siguiente palabra */
tmp=strtok(NULL, delim);
} while (tmp!=NULL);

*args=aargs;
return num;
}

int main()
{
char cadena[]="Bienvenido al blog Poesía Binaria. Esto es una prueba del extractor de argumentos con puntero triple";
char **args4;
int i;
int nargs;

nargs=extrae_argumentos_ddg(cadena, " ", &amp;args4);

printf("CADENA: %s\n", cadena);
for (i=0; i&lt;nargs;i++)
printf("Palabra %d: %X "%s"\n", i, *args4[i], args4[i]);
}

Actualización 25/10/2016 : Añadida foto principal

Foto: Dan Edwards

También podría interesarte...

Leave a Reply