codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char **explode(const char sep, char *str);
int main(void)
{
int i;
char **test/*,
**test2 = explode(',', ""),
**test3 = explode(',', ",lol,987,*è,,")*/;
/*for (i = 0; i < strlen(test); i++) {}*/
for (i = 0; i < 1; i++) {
/* test = explode(',', "asd,123,-1");
100000000
real 0m24.126s
user 0m24.116s
sys 0m0.000s */
test = explode(',', "asd,123,-1");
}
return 0;
}
char **explode(const char sep, char *str)
{
short int numElem = 0, numChars = 0, i, ii;
char **ret;
char *pt = str;
short int stop = 0;
while (*str || *str == '\0') {
if (*str == sep || *str == '\0') {
numElem++;
if (*str == '\0') {
break;
}
}
str++;
}
ret = (char**) malloc(sizeof(char*) * numElem);
printf(" ret = (char**) malloc(sizeof(char*) * %d)\n\n\n", numElem);
/*
The rapresentation of this for the string "asd,123,-1" is:
numElem = 3
+---+---+---+---+
1 | a | s d \n|
+---+---+---+---+
2 | 1 | 2 3 \n|
+---+---+---+---+
3 | - | 1 \n|
+---+---+---+
printf("%s", ret[0]) = "asd\n"
...
*/
if (ret == NULL) {
puts("Error");
exit(1);
}
/* Reset the pointer */
str = pt;
for (i = 0; i < numElem; i++) {
if (stop == 1) {
break;
}
while (*str || *str == '\0') {
if (*str == sep || *str == '\0') {
ret[i] = (char*) malloc(sizeof(char) * ++numChars);
printf(" ret[%d] = (char*) malloc(sizeof(char) * %d)\n", i, numChars);
numChars = 0;
if (*str == '\0') {
stop = 1;
} else {
*(str++);
}
break;
}
else {
numChars++;
}
str++;
}
}
printf("\n\n");
/* Reset the pointer */
str = pt;
/* Assign the letters */
stop = numChars = 0;
for (i = 0; i < numElem; i++) {
if (stop == 1) {
break;
}
while (*str || *str == '\0') {
if (*str == sep || *str == '\0') {
ret[i][numChars] = '\0';
printf(" ret[%d][%d] = \\0\n", i, numChars);
numChars = 0;
if (*str == '\0') {
stop = 1;
} else {
*(str++);
}
break;
}
else {
ret[i][numChars] = *str;
printf(" ret[%d][%d] = %c\n", i, numChars, *str);
numChars += 1;
str++;
}
}
}
printf("\n\n");
/* Result */
for (i = 0; i < (numElem + 0); i++) {
printf(" string %d: %s\n", i, ret[i]);
}
/* Free memory */
for (i = 0; i < numElem; i++) {
free(ret[i]);
}
free(ret);
return ret;
}
matias@matias-desktop:~/Desktop$ valgrind ./try
==15470== Memcheck, a memory error detector
==15470== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==15470== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==15470== Command: ./try
==15470==
ret = (char**) malloc(sizeof(char*) * 3)
ret[0] = (char*) malloc(sizeof(char) * 4)
ret[1] = (char*) malloc(sizeof(char) * 4)
ret[2] = (char*) malloc(sizeof(char) * 3)
ret[0][0] = a
ret[0][1] = s
ret[0][2] = d
ret[0][3] = \0
ret[1][0] = 1
ret[1][1] = 2
ret[1][2] = 3
ret[1][3] = \0
ret[2][0] = -
ret[2][1] = 1
ret[2][2] = \0
string 0: asd
string 1: 123
string 2: -1
==15470==
==15470== HEAP SUMMARY:
==15470== in use at exit: 0 bytes in 0 blocks
==15470== total heap usage: 5 allocs, 5 frees, 1,059 bytes allocated
==15470==
==15470== All heap blocks were freed -- no leaks are possible
==15470==
==15470== For counts of detected and suppressed errors, rerun with: -v
==15470== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Per quanto il codice faccia schifo (ne sono consapevole) ora funziona senza errori. Avrei potuto snellirlo notevolmente con l'utilizzo di realloc/strtok/strcpy ma ero interessato al fine didattico.
Grazie per l'aiuto.