Convert String into Array of Strings in C

So we basically loop through the string, and check if we found the "split character' and we also check that we didn't find the 'curr_letter' as the next character.

We keep track of the consumed length, the current length (used for memcpy later to copy the current string to the array).

When we find a position where we can add the current string to the array, we allocate space and copy the string to it as the next element in the array. We also add the current_length to consumed, and the current_length is reset.

We use due_to_end to find out if we have a / in the current string, and remove it accordingly.

Try:

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

int main() {
        char *str = "a/apple/arm/basket/bread/car/camp/element/...";
        char split_char = '/';
        char nosplit_char = 'a';

        char **array = NULL;
        int num_elts = 0;

        // read all the characters one by one, and add to array if 
        // your condition is met, or if the string ends
        int current_length = 0; // holds the current length of the element to be added
        int consumed = 0; // holds how much we already added to the array
        for (int i = 0; i < strlen(str); i++) { // loop through string
                current_length++; // increment first
                int due_to_end = 0;
                if ( ( str[i] == split_char // check if split character found
                    && ( i != (strlen(str) - 1) // check if its not the end of the string, so when we check for the next character, we don't overflow
                    && str[i + 1] != nosplit_char ) ) // check if the next char is not the curr_letter(nosplit_char)
                   || (i == strlen(str) - 1 && (due_to_end = 1))) { // **OR**, check if end of string
                        array = realloc(array, (num_elts + 1) * sizeof(char *)); // allocate space in the array
                        array[num_elts] = calloc(current_length + 1, sizeof(char)); // allocate space for the string
                        memcpy(array[num_elts++], str + consumed, (due_to_end == 0 ? current_length - 1 : current_length)); // copy the string to the current array offset's allocated memory, and remove 1 character (slash) if this is not the end of the string

                        consumed += current_length; // add what we consumed right now
                        current_length = 0; // reset current_length
                }
        }

        for (int i = 0; i < num_elts; i++) { // loop through all the elements for overview
                printf("%s\n", array[i]);
                free(array[i]);
        }
        free(array);
}

Yes, the approach that you specify in your question seems good, in principle. However, I see the following problem:

Using strcpy will require a null-terminated source string. This means if you want to use strcpy, you will have to overwrite the / with a null character. If you don't want to have to modify the source string by writing null characters into it, then an alternative would be to use the function memcpy instead of strcpy. That way, you can specify the exact number of characters to copy and you don't require the source string to have a null terminating character. However, this also means that you will somehow have to count the number of characters to copy.

On the other hand, instead of using strcpy or memcpy, you could simply copy one character at a time from str into arr[0], until you encounter the next letter, and then copy one character at a time from str into arr[1], and so on. That solution may be simpler.

In accordance with the community guidelines for homework questions, I will not provide a full solution to your problem at this time.

EDIT: Since another answer has already provides a full solution which uses memcpy, I will now also provide a full solution, which uses the simpler solution mentioned above of copying one character at a time:

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

#define NUM_LETTERS 26
#define MAX_CHARS_PER_LETTER 99

int main( void )
{
    //declare the input string
    char *str =
        "a/apple/arm/basket/bread/car/camp/element/"
        "frog/glass/saddle/ship/water";

    //declare array which holds all the data
    //we must add 1 for the terminating null character
    char arr[NUM_LETTERS][MAX_CHARS_PER_LETTER+1];

    //this variable will store the current letter that we
    //have reached
    char curr_letter = 'a';

    //this variable will store the number of chars that are
    //already used in the current letter, which will be a
    //number between 0 and MAX_CHARS_PER_LETTER
    int chars_used = 0;

    //this variable stores whether the next character is
    //the start of a new word
    bool new_word = true;

    //initialize the arrays to contain empty strings
    for ( int i = 0; i < NUM_LETTERS; i++ )
        arr[i][0] = '\0';

    //read one character at a time
    for ( const char *p = str; *p != '\0'; p++ )
    {
        //determine whether we have reached the end of a word
        if ( *p == '/' )
        {
            new_word = true;
        }
        else
        {
            //determine whether we have reached a new letter
            if ( new_word && *p != curr_letter )
            {
                //write terminating null character to string of
                //previous letter, overwriting the "/"
                if ( chars_used != 0 )
                    arr[curr_letter-'a'][chars_used-1] = '\0';

                curr_letter = *p;
                chars_used = 0;
            }

            new_word = false;
        }

        //verify that buffer is large enough
        if ( chars_used == MAX_CHARS_PER_LETTER )
        {
            fprintf( stderr, "buffer overflow!\n" );
            exit( EXIT_FAILURE );
        }

        //copy the character
        arr[curr_letter-'a'][chars_used++] = *p;
    }

    //the following code assumes that the string pointed to
    //by "str" will not end with a "/"

    //write terminating null character to string
    arr[curr_letter-'a'][chars_used] = '\0';

    //print the result
    for ( int i = 0; i < NUM_LETTERS; i++ )
        printf( "%c: %s\n", 'a' + i, arr[i] );
}

This program has the following output:

a: a/apple/arm
b: basket/bread
c: car/camp
d: 
e: element
f: frog
g: glass
h: 
i: 
j: 
k: 
l: 
m: 
n: 
o: 
p: 
q: 
r: 
s: saddle/ship
t: 
u: 
v: 
w: water
x: 
y: 
z: 

Here is another solution which uses strtok:

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

#define NUM_LETTERS 26
#define MAX_CHARS_PER_LETTER 99

int main( void )
{
    //declare the input string
    char str[] =
        "a/apple/arm/basket/bread/car/camp/element/"
        "frog/glass/saddle/ship/water";

    //declare array which holds all the data
    //we must add 1 for the terminating null character
    char arr[NUM_LETTERS][MAX_CHARS_PER_LETTER+1];

    //this variable will store the current letter that we
    //have reached
    char curr_letter = 'a';

    //this variable will store the number of chars that are
    //already used in the current letter, which will be a
    //number between 0 and MAX_CHARS_PER_LETTER
    int chars_used = 0;

    //initialize the arrays to contain empty strings
    for ( int i = 0; i < NUM_LETTERS; i++ )
        arr[i][0] = '\0';

    //find first token
    char *p = strtok( str, "/" );

    //read one token at a time
    while ( p != NULL )
    {
        int len;

        //determine whether we have reached a new letter
        if ( p[0] != curr_letter )
        {
            curr_letter = p[0];
            chars_used = 0;
        }

        //count length of string
        len = strlen( p );
            
        //verify that buffer is large enough to copy string
        if ( chars_used + len >= MAX_CHARS_PER_LETTER )
        {
            fprintf( stderr, "buffer overflow!\n" );
            exit( EXIT_FAILURE );
        }

        //add "/" if necessary
        if ( chars_used != 0 )
        {
            arr[curr_letter-'a'][chars_used++] =  '/';
            arr[curr_letter-'a'][chars_used]   = '\0';
        }

        //copy the word
        strcpy( arr[curr_letter-'a']+chars_used, p );

        //update number of characters used in buffer
        chars_used += len;

        //find next token
        p = strtok( NULL, "/" );
    }

    //print the result
    for ( int i = 0; i < NUM_LETTERS; i++ )
        printf( "%c: %s\n", 'a' + i, arr[i] );
}