Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C - Split a string at the whitespaces

Tags:

c

split

I need to split a string where there are spaces (ex string: Hello this is an example string. into an array of words. I'm not sure what I'm missing here, I'm also curious as to what the best way to test this function is. The only library function allowed is malloc.

Any help is appreciated!

#include <stdlib.h>

char **ft_split(char *str) {
    int wordlength;
    int wordcount;
    char **wordbank;
    int i;
    int current;

    current = 0;
    wordlength = 0;
    //while sentence
    while (str[wordlength] != '\0') {
        //go till letters
        while (str[current] == ' ')
            current++;
        //go till spaces
        wordlength = 0;
        while (str[wordlength] != ' ' && str[wordlength] != '\0')
            wordlength++;
         //make memory for word
        wordbank[wordcount] = malloc(sizeof(char) * (wordlength - current + 1));

        i = 0;
        //fill wordbank current
        while (i < wordlength - current) {
            wordbank[wordcount][i] = str[current];
            i++;
            current++;
        }

        //end word with '\0'
        wordbank[wordcount][i] = '\0';

        wordcount++;
    }
    return wordbank;
}
like image 720
Nick Avatar asked Jun 28 '26 09:06

Nick


1 Answers

There are multiple problems in your code:

  • You do not allocate an array for wordbank to point to, dereferencing an uninitialized pointer has undefined behavior.
  • Your approach to scanning the string is broken: you reset wordlength inside the loop so you keep re-scanning from the beginning of the string.
  • You should allocate an extra entry in the array for a trailing null pointer to indicate the end of the array to the caller.

Here is a modified version:

#include <stdlib.h>

char **ft_split(const char *str) {
    size_t i, j, k, wordcount;
    char **wordbank;

    // count the number of words:
    wordcount = 0; 
    for (i = 0; str[i]; i++) {
        if (str[i] != ' ' && (i == 0 || str[i - 1] == ' ')) {
            wordcount++;
        }
    }

    // allocate the word array
    wordbank = malloc((wordcount + 1) * sizeof(*wordbank));
    if (wordbank) {
        for (i = k = 0;;) {
            // skip spaces
            while (str[i] == ' ')
                i++;
            // check for end of string
            if (str[i] == '\0')
                break;
            // scan for end of word
            for (j = i++; str[i] != '\0' && str[i] != ' '; i++)
                continue;
            // allocate space for word copy
            wordbank[k] = p = malloc(i - j + 1);
            if (p == NULL) {
                // allocation failed: free and return NULL
                while (k-- > 0) {
                    free(wordbank[k]);
                }
                free(wordbank);
                return NULL;
            }
            // copy string contents
            memcpy(p, str + j, i - j);
            p[i - j] = '\0';
        }
        // set a null pointer at the end of the array
        wordbank[k] = NULL;
    }
    return wordbank;
}
like image 107
chqrlie Avatar answered Jun 30 '26 23:06

chqrlie



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!