Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

splitting a string using '\0'

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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>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"
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading