splitting a string using '\0'

Advertisements

let’s say I have a char* ./a.out\0a\0b\0\0.
I want to split it and the result to be a char** of value

{
    "./a.out\0",
    "a\0",
    "b\0",
    "\0"
}

I’m using pure c + POSIX but if an answer contains parts of the c++STL I don’t mind that, just avoid the memory inefficient ones like std::string

>Solution :

Here is a simple way to populate an array of pointers from your composite string, assuming you know how many strings are adjacent:

#include <stdio.h>
#include <string.h>

int main() {
    const char *str = "./a.out\0a\0b\0";  // 3 strings
    const char *args[3];

    const char *p = str;
    for (int i = 0; i < 3; i++) {
        args[i] = p;
        p += strlen(p) + 1;
    }

    for (int i = 0; i < 3; i++) {
        printf("args[%d] = \"%s\"\n", i, args[i]);
    }

    return 0;
}

Output:

args[0] = "./a.out"
args[1] = "a"
args[2] = "b"

Here is an alternative encapsulated as a function that allocates an array, scanning the byte array to determine the number of strings, relying on 2 consecutive null bytes to indicate the end of the list:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char **split(const char *str) {
    const char **array;
    const char *p;
    int count = 0, i;

    // count the number of strings
    for (p = str; *p; p += strlen(p) + 1) {
        count++;
    }
    // allocate the array with an extra element for a NULL terminator
    array = calloc(sizeof(*array), count + 1);
    if (array != NULL) {
        // populate the array with pointers into the string
        for (i = 0, p = str; i < count; i++, p += strlen(p) + 1) {
            array[i] = p;
        }
        // set the NULL terminator
        array[i] = NULL;
    }
    return array;
}

int main() {
    const char *str = "./a.out\0a\0b\0";  // 4 strings
    const char **args = split(str);

    for (int i = 0; args[i] != NULL; i++) {
        printf("args[%d] = \"%s\"\n", i, args[i]);
    }
    return 0;
}

Output:

args[0] = "./a.out"
args[1] = "a"
args[2] = "b"

Leave a ReplyCancel reply