简体   繁体   中英

Split an array of strings based on character

I have an array of strings similar to this:

char* arrStrings[] = {"a", "be", "|", "cgg", "dss", "|", "mmd", "ddd", "\0"}

1) I would like to be able to be able to split this into a set of arrays, based on where the '|' character is.

So, after splitting, I would have this:

a1 = {"a", "be", "\0"}
a2 = {"cgg", "dss", "\0"}
a3 = {"mmd", "ddd", "\0"}

2) After that, I need to create a linked list that has all 3 arrays, like this:

list = {pointer to a1, pointer to a2, pointer to a3}

I'm very confused about it, since there are multiple levels of pointers involved. How can I accomplish this?

If you can use NULL as delimiter in the list, you don't need to duplicate the strings, just use an array of pointers to string.

*arrStrings[] = {"a", "be", "|", "cgg", "dss", "|", "mmd", "ddd", ""};

is transformed into

*arr       [] = {"a", "be", NULL, "cgg", "dss", NULL, "mmd", "ddd", NULL};

Once you have filled the array you can use an array of pointers to pointer to string to create the list:

*arr       [] = {"a", "be", NULL, "cgg", "dss", NULL, "mmd", "ddd", NULL};
**ptr      [] = { ^                 ^                   ^               };

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

int main(void)
{
    /* The array */
    char *arrStrings[] = {"a", "be", "|", "cgg", "dss", "|", "mmd", "ddd", ""};
    /* Elements of the array */
    size_t sz = sizeof(arrStrings) / sizeof(arrStrings[0]);
    /* Loop */
    size_t i, n = 0;
    /* Create an array (VLA) of n pointers */
    char *arr[sz];

    /* Count the number of delimiters and fill array */
    for (i = 0; i < sz; i++) {
        /* If we found a delimiter assign NULL */
        if (strcmp(arrStrings[i], "|") == 0) {
            arr[i] = NULL;
            n++;
        } else
        /* If we found an empty string assign NULL */
        if (arrStrings[i][0] == '\0') {
            arr[i] = NULL;
        } else {
            arr[i] = arrStrings[i];
        }
    }
    /* Create an array (VLA) of n delimiters pointers to pointer */
    char **ptr[n + 1];
    ptr[0] = &arr[0];
    for (i = n = 0; i < sz - 1; i++) {
        /* For each NULL string push address of array + 1 into ptr */
        if (arr[i] == NULL) {
            ptr[++n] = &arr[i + 1];
        }
    }
    /* For each pointer to pointer loop and print until NULL */
    char **str;
    for (i = 0; i <= n; i++) {
        str = ptr[i];
        printf("%zu)\n", i);
        while (*str != NULL) {
            printf("\t%s\n", *str);
            str++;
        } 
    }
    return 0;
}

Output:

0)
    a
    be
1)
    cgg
    dss
2)
    mmd
    ddd

The first thing you have to know is that an array of strings is a pointer to a fixed number of further pointers to characters

arrString --> |_|_|_| ... |_|
               | | |       |
               V V V       V
               a b |       \0
                 e

therefore you cannot simply update the "|" element with "\\0" and manage the string as it would be the "strtok" function for example. Rather, you have to allocate three new "char**" array to maintain the three "char*" sequences, and use them to create the list as you prefer.

In case you want to avoid the allocation of new memory space, then you have to implement customized facilities, in order to parse the "char**" array according to its formatting. In this way you can really have three pointers to three different positions in "arrString", which define the first sub-string that belongs to the interested array. The final element "|" or "\\0" will indicate no further elements belong to it. However, as I already said, this requires you implement ad-hoc functions, which avoid to alter the array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM