Search code examples
c++arduinooverloading

How can I use __FlashStringHelper* in a function which takes char*?


I managed to figure the answer to this out myself, but it took far too long. (I'm an arduino and C++ newbie).

Question: How can I use strings written like F("long string to store in flash memory instead of RAM") (__FlashStringHelper) as if it were just a string like "normal string" (const char*).

E.g.

void doSomethingWithText(const char *text) {
   char* buffer[17];
   strncpy(buffer, text, 16); 
   Serial.println(buffer);
}

Where

doSomethingWithText("Use this text");  // WORKS
doSomethingWithText(F("Use this text instead");  // RAISES COMPILE ERROR

Compile Error:

no known conversion for argument 1 from 'const __FlashStringHelper*' to 'const char*'

Note: I am aware that this question is similar to (How can I compare __FlashStringHelper* with char* on Arduino?), but it took me a long time to come across when I just wanted to know the answer to the question above.


Solution

  • To make the function also work with the F("..."), add a function overload that takes const __FlashStringHelper* as an argument instead. e.g.

    // This one stays the same
    void doSomethingWithText(const char *text) {
       char* buffer[17];
       strncpy(buffer, text, 16);
       Serial.println(buffer);
    }
    
    // This will be used in the case where the argument is F("....")
    void doSomethingWithText(const __FlashStringHelper *text) {
       char buffer[17];
       strncpy_P(buffer, (const char*)text, 16);  // _P is the version to read from program space
       Serial.println(buffer);
    }
    

    The three key parts are: overloading the function to account for the different argument type, using the _P version of various string functions, casting the __FlashStringHelper back to a const char*.

    Note: For this simple case the text could be passed to Serial.println(text) directly.