简体   繁体   中英

Passing pointer to char* array into function to manipulate values on Arduino

[PLEASE CHECK FINAL EDIT BELOW FOR UPDATE]

My C++ is a bit rusty (to say the least) and I'm having an issue trying to pass a char array into a function to manipulate the values. Example code below:

void myFunction(char* splitStrings,String stringToSetInLoop) {
  char substringPtr[stringToSetInLoop.length()];
  stringToSetInLoop.toCharArray(substringPtr, stringToSetInLoop.length());

  for(int i = 0; i < 10; i++) {
       splitStrings[i] = *substringPtr;
   }
}

char *mySplitStrings[10];
myFunction(*mySplitStrings,String("Repeat Me"));
Serial.println(mySplitStrings[0]);

The code does not crash, but it outputs a blank line. I suspect that I need to initialize a 2 dimensional array outside the function to pass in so that memory space is allocated. I'm guessing that, although the substring pointer exists inside the function, the memory is destroyed, leaving the char* array mySplitStrings[0 ] pointing at nothing. Also, I think I need to pass in the reference to the array memory space, not as a pointer.

The ultimate goal here is to be able to pass a char array into a function, assign some values to it, then use those values back in the main code loop. If there's a better way to achieve this, then please let me know.

Thanks in advance. Please free me from my personal pointer/reference hell!

EDIT: Further note, this code is being run on an arduino, so the C++ is limited.

EDIT: When I try to pass in a reference to the char* pointer, I get this error, which I'm not sure how to change the function parameters to fix: error: cannot convert char* ()[10] to char for argument 1 to void myFunction(char*, String) . Can anybody please take a stab at showing me a working example?

EDIT:

Thanks to the responses... I now have a working static library function that splits strings passed as a char* array. I know it's not pretty, but it does work. Thanks you to those who contributed. Code below:

void ExplodeString::explode(char* explodeResults[], String str, String delimiter) {
    int delimiterPosition;
    int explodeResultsCounter=0;
    String subString;
    do {
        delimiterPosition = str.indexOf(delimiter);
        if(delimiterPosition != -1) {
            subString = str.substring(0,delimiterPosition);
                char *subStringPtr[subString.length()+1];
                subString.toCharArray(*subStringPtr, subString.length()+1);
                explodeResults[explodeResultsCounter++] = strdup(*subStringPtr);
                str = str.substring(delimiterPosition+1, str.length());
        } else {  // here after the last delimiter is found
            if(str.length() > 0) {
                     subString = str;
                     char *subStringLastPtr[subString.length()+1];
                     subString.toCharArray(*subStringLastPtr, subString.length()+1);
                     explodeResults[explodeResultsCounter++] = strdup(*subStringLastPtr);
             }
        }
    } while (delimiterPosition >=0);
}

Usage:

char* explodeResults[10];
ExplodeString::explode(explodeResults, String("cat:dog:chicken"), String(":"));
Serial.println(explodeResults[0]);
Serial.println(explodeResults[1]);
Serial.println(explodeResults[2]);

EDIT: Man, this is sooo much easier when you use the stdlib:

void ExplodeString::explode(std::vector<std::string> &explodeResults, std::string str, char delimiter) {
    std::stringstream data(str);
    std::string line;
    while(std::getline(data,line,delimiter))
    {
        explodeResults.push_back(line);
    }
}

Usage:

std::vector<std::string> commandsResult;
char delimiter[] = ",";
std::string _inputString = "my,string,to,parse";
ExplodeString::explode(commandsResult, _inputString, delimiter[0]);

How to pass an array of char*:

void myFunction(char* splitStrings[10], String stringToSetInLoop) {
// ...

char *mySplitStrings[10];
myFunction(mySplitStrings, String("Repeat Me"));

This will also work:

void myFunction(char* splitStrings[], String stringToSetInLoop) {

and this:

void myFunction(char** splitStrings, String stringToSetInLoop) {

Also, seems there is STL for avr platform - include it, C++ without STL is smth strange.

You are not allocating space for character arrays and just passing pointer of character array. Instead of using char*splitStrings[10], you can use 2d char array with sufficient space to accomodate max length string. Assuming you max string length is less that 64 you can do something like this.

  char splitString[10][64];

    void myFunction(char**splitStrings,String stringToSetInLoop) 
    or
    void myFunction(char splitString[][64], String stringToSetInLoop)
    {
      int len = stringToSetInLoop.length();
      for(int i = 0; i<10; i++)
      {
        for(int j = 0; i<len; j++)
       {
         splitString[i][j] = stringToSetInLoop.charAt(j);
       }
    }

    }

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