I am trying to implement a split funtion, which receives an array of chars and a delimiter that will decide what chars go to each array in the split array.
I have a problem with strcat and memset, can somone explain my mistakes to me?
char** split(const char* str, char delimiter)
{
int ch=0;
int word=0;
const char * zero="\0";
unsigned int size=num_items(str,delimiter);
/* get the size of split[][] */
char** split= calloc(size+1,sizeof(char*));
for(int i=0; i<strlen(str); i++)
{
if(ch==0)
{
memset(split[word],'\0',1);
/* set the first value to '\0' */
ch++;
}
if(str[i]!=delimiter)
{
/* adding char by char to the split */
strcat(split[word],&str[i]);
ch++;
}else{
ch=0;
word++;
}
}
return split;
}
Memory needs to be allocated for the pointers and the strings they point to.
For a single character, it can be assigned directly. No need for strcat
and strcat
expects pointers to zero terminated strings.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char** split(const char* str, char delimiter)
{
char** split= NULL;
int ch=0;
unsigned int size=0;
size_t len = strlen ( str);
for(int i=0; i<len; i++)
{
if(ch==0)
{
char** temp= realloc(split, sizeof *split * (size+2));//allocate pointer
if ( ! temp) {
fprintf ( stderr, "problem malloc\n");
return split;
}
split = temp;
split[size] = calloc ( 1, len + 1);//allocate for string
if ( ! split[size]) {
fprintf ( stderr, "problem calloc\n");
return split;
}
split[size + 1] = NULL;//sentinel
}
if(str[i]!=delimiter)
{
split[size][ch] = str[i];//assign character
ch++;
}else{
size_t length = strlen ( split[size]);
char *tmp = realloc ( split[size], length + 1);//reallocate to exact size
if ( ! tmp) {
fprintf ( stderr, "problem realloc\n");
return split;
}
ch=0;
size++;
}
}
return split;
}
int main ( void) {
char **words = NULL;
char *text = "a bc def ghij klmno pqr st u v wzyx";
char space = ' ';
words = split ( text, space);
int each = 0;
while ( words && words[each]) {
printf ( "%s\n", words[each]);
++each;
}
each = 0;
while ( words && words[each]) {
free ( words[each]);
++each;
}
free ( words);
return 0;
}