Search code examples
cstringsplitnul

split a char array into tokens where the separator is NUL char


I want to split a char array into tokens using the NUL char as the separator.

I have a char array that I've received over the network from a recv command, so I know the length of the char array. In that char array there are bunch of strings that are separated by the NUL char (\0).

Because the separator is the NUL char, that means I can't use strtok, because it uses NULL for its own purposes.

So I want to iterate through all the strings starting from byte 8 (the strings are preceded by 2 32 bit integers).

I was thinking I could iterate though all the characters looking for the \0 character and then doing a memcpy of the length I have found so far, but I figured there must be a nicer method than this.

What other approach can I take?


Solution

  • Here is some simple code showing how you can get the contained strings:

    #include <stdio.h>
    #include <string.h>
    
    int main(void) {
        char recbuf[7] = {'a', 'b', 'c', '\0', 'd', 'e', '\0'};
        int recbuf_size = 7;
        int j = 0;
        char* p = recbuf;
        while(j < recbuf_size) 
        {
            printf("%s\n", p);  // print the string found
                                // Here you could copy the string if needed, e.g.
                                // strcpy(mySavedStrings[stringCount++], p);
    
            int t = strlen(p);  // get the length of the string just printed
            p += t + 1;         // move to next string - add 1 to include string termination
            j += t + 1;         // remember how far we are
        }
        return 0;
    }
    

    Output:

    abc
    de
    

    If you need to skip some bytes in the start of the buffer then just do:

    int number_of_bytes_to_skip = 4;
    int j = number_of_bytes_to_skip;
    char* p = recbuf + number_of_bytes_to_skip;
    

    Notice:

    The code above assumes that the receive buffer is always correctly terminated with a '\0'. In real world code, you should check that before running the code and add error handling, e.g.:

    if (recbuf[recbuf_size-1] != '\0')
    {
        // Some error handling...
    }