Continuing from my comment, you can tokenize your string with, e.g. strtok and assign the pointers to the individual words to a pointer-to-pointer-to-char. For example:
#include <stdio.h>
#include <string.h>
#define MAX 10
int main (void) {
char *cmd = (char[]){"a bcd ef hijk lmmopq"}, /* compound literal */
// char cmd[] = "a bcd ef hijk lmmopq"; /* otherwise declare as array */
*arr[MAX] = {NULL},
*delim = " \n";
size_t n = 0;
for (char *p = strtok (cmd, delim); n < MAX && p; p = strtok (NULL, delim))
arr[n++] = p;
for (int i = 0; i < (int)n; i++)
printf ("arr[%d]: %s\n", i, arr[i]);
return 0;
}
*Example Use/Output**
$./bin/str2ptp
arr[0]: a
arr[1]: bcd
arr[2]: ef
arr[3]: hijk
arr[4]: lmmopq
Note: You cannot pass a string literal to strtok as strtok modifies the string. Either use a pointer to an array or declare and initialize as a normal char[] array to begin with.
Dynamically allocating pointer for unknown number of words
If you have no idea whether you could read twenty words or 2000 words, you can easily handle the situation by dynamically allocating blocks of pointers, and then reallocating again if the prior max allocation is again reached. It is a simple process, e.g.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 10
#define MAXB 4096
int main (void) {
char cmd[MAXB] = "", /* buffer of 4096 chars to hold each line input */
**arr = calloc (MAX, sizeof *arr),
*delim = " \n";
size_t n = 0, max = MAX;
while (fgets (cmd, MAXB, stdin)) { /* read each line of input on stdin */
size_t len = strlen (cmd); /* get line length */
if (cmd[len - 1] == '\n') /* test for trailing '\n' */
cmd[--len] = 0; /* overwrite with nul-byte */
for (char *p = strtok (cmd, delim); p; p = strtok (NULL, delim)) {
arr[n++] = p;
if (n == max) { /* realloc arr by MAX if n == MAX */
void *tmp = realloc (arr, (max + MAX) * sizeof *arr);
if (!tmp) {
fprintf (stderr, "error: memory exhausted.\n");
break;
}
arr = tmp; /* zero new pointers (optional) */
memset (arr + max, 0, MAX * sizeof *arr);
max += MAX; /* update current max iteration */
}
}
for (int i = 0; i < (int)n; i++)
printf ("arr[%2d]: %s\n", i, arr[i]);
}
free (arr); /* don't forget, if you allocate it -> you free it. */
return 0;
}
Above, always validate your allocations with, e.g. if (!arr) { /* handle error */ } which was omitted from the initial allocation of arr for brevity.
Example Use/Input
$ echo "A quick brown fox jumps over the lazy dog while the dog watched" | \
./bin/strtop2pdyn
arr[ 0]: A
arr[ 1]: quick
arr[ 2]: brown
arr[ 3]: fox
arr[ 4]: jumps
arr[ 5]: over
arr[ 6]: the
arr[ 7]: lazy
arr[ 8]: dog
arr[ 9]: while
arr[10]: the
arr[11]: dog
arr[12]: watched
char** argvis not a 2D array, but a pointer to a pointer.char a[3][4]is a 2D array.strtokorstrsepor by simply walking a pair of pointers down your string an identifying the individual words directly and assigning each word to a successive pointer-to-pointer-to-char or by copying the words to a 2D array of chars of sufficient size..cmdstring? Do you need to keep this string in one place and not copy it anywhere?