Splitting char[] to another array

Hello code guru !

I’m facing a new issue with my projet. I try to split an array of string from a user input. User is sending command with argument. To easily process it, i want to split user input to an array of string. But this is where i failed.

Here is the relevant portion of code, *pOutString will be used later to handle command and args. And maxNumberOfargs is a value equal to size the array size definition

[some code]
//char commandAndArgs[4][30]; we expect 4 array_rows of 30 char max each
char **commandAndArgs[ROWSIZE][30];
myclass.splitToArray(pUserCommand, commandAndArgs, ROWSIZE );

[some more code]
//my method 
void MyClass::splitToArray(char *pInString, char *pOutString, int maxNumberOfargs)
{
  const char delimiters[] = "!:, ";
  char* val;
  int index=0;

  val = strtok (pInString, delimiters);
  while (val != NULL && index < maxNumberOfargs - 1 ) //-1 for index0 of array
  {
    pOutString[index] = val;
    val = strtok (NULL, delimiters);
  }
}
[code]

I'm pretty sure *pOutString should be declared as an array of pointers (char **) but each time i try to do it... I fail.

Can someone do some light ?

Thank you for your time and advices.
BR
  val = strtok (pInString, delimiters);
  while (val != NULL && index < maxNumberOfargs - 1 ) //-1 for index0 of array
  {
    pOutString[index] = val;
    val = strtok (NULL, delimiters);

val is a pointer. Storing the pointer in an array of pointers is NOT the same as saving the pointed-to data.

At the end, all elements of the pOutString array are going to contain the same pointer, and all elements are going to point to the same thing.

    pOutString[index] = strdup(val);

on the other hand, WILL duplicate the pointed-to data. so that pOutString ends up containing many different pointers, pointing to different data.

Do NOT forget to free the memory pointed to by the pOutString elements.

Thank you PaulS !

I'd look to strdup. Thanks for pointing me this function.

I still have error on compiling :

error: no matching function for call to 'myClass::splitToArray(char*&, char [4][30], int)'

  this->splitToArray(pUserCommand, commandAndArgs, 4 );

                                                                                      ^

Method prototype is :

void splitToArray(char* pInString, char** pOutString, int maxNumberOfargs);

And is called by this way, I also tryied to use other variant (commented). But as array is already a "pointer" it fails too.

char commandAndArgs[4][30] = {"0"} ;
//char* pCommandAndArgs = commandAndArgs;
//this->splitToArray(pUserCommand, pCommandAndArgs, 4 );

this->splitToArray(pUserCommand, commandAndArgs, 4 );

One more info

PaulS:
Do NOT forget to free the memory pointed to by the pOutString elements.

By using free(pUserCommand) when using the var is done ?
But... This var is used only in setup() for now so it will be deleted on the end of setup() right ?

Bye.
BR

char **commandAndArgs[ROWSIZE][30];

This is a 2D array of pointers to pointers to char. That is almost certainly NOT what you want. I think you want a 2D array of chars.

You don’t need an array of arrays of pointers to pointers. You just need an array of pointers.

char *commandAndArgs[ROWSIZE];
myclass.splitToArray(pUserCommand, commandAndArgs, ROWSIZE );

[some more code]

//my method 
void MyClass::splitToArray(char *pInString, char *pOutString[], int maxNumberOfargs)
{
  const char delimiters[] = "!:, ";
  char *val;
  int index=0;

  val = strtok (pInString, delimiters);
  while (val != NULL && index < maxNumberOfargs - 1 ) //-1 for index0 of array
  {
    pOutString[index] = val;
    val = strtok (NULL, delimiters);
  }
}

I’m not entirely sure that the argument doesn’t have to be "char (*pOutString)’. It’s possible that ‘char **pOutString’ would also work when used as a function argument.

Hey !

Here the final code I use for those interested ! Thanks you all for your help.

void splitToArray(char* pInString, char **pOutString, int maxNumberOfargs);


void TERMINALSYNC::splitToArray(char* pInString, char **pOutString , int maxNumberOfargs)
{
  const char delimiters[] = "- ";
  char* val;
  int index=0;

  val = strtok(pInString, delimiters);
  while (val != NULL && index <= (maxNumberOfargs - 1) ) //-1 for index0 of array
  {
    pOutString[index] = strdup(val);
    val = strtok(NULL, delimiters);
    index++;
  }
}