Go Down

Topic: Building a long string (Read 188 times) previous topic - next topic

Dr_Quark

Is there a way to build a long string, without terminating nulls between phrases, using a structure similar to the following? Having the sub-strings on individual lines is important for readability and comments. All the sub-strings are identical in length.

   char* const text[] PROGMEM = {
        "string1",           // comments
        "string2",           // more comments
        ...
        "string40" } ;

Thanks.
Dr.Quark

Danois90

#1
Oct 15, 2018, 08:42 pm Last Edit: Oct 15, 2018, 08:43 pm by Danois90
If you do not need the substrings to be an array, you could ditch the commas. Somethind like this should work (untested):

Code: [Select]
const char TEXT[] PROGMEM = "Token1" // Comments
                          "Token2" // More comments
                          "Last one"; // Yup, the end!

Serial.println(TEXT);


If you need the array, then you must programmatically concat the substrings into another buffer.
Instead of mocking what's wrong, teach what's right! ;)
When you get help, remember to thank the helper and give some karma!
Please, do NOT send me any private messages!!

Dr_Quark

Thanks, now I just need to learn how to read one substring at a time into a RAM string so I can lcd.print() it.
Dr.Quark

DKWatson

Remember that the array name TEXT is in fact a pointer and is the base address of the array, so any reference to PROGMEM would be relative to the base address plus the offset which is the index into the array.
Live as if you were to die tomorrow. Learn as if you were to live forever. - Mahatma Gandhi

gfvalvo

Thanks, now I just need to learn how to read one substring at a time into a RAM string so I can lcd.print() it.
If all you want to do is print it, you don't need to read it into RAM yourself. Assuming the 'Lcd' class inherits from the 'Print' class, its 'print' method knows how to deal with a '__FlashStringHelper *'. So, with proper casting, you can get the lcd object to do the reading into RAM for you.

Whandall

If all you want to do is print it, you don't need to read it into RAM yourself. Assuming the 'Lcd' class inherits from the 'Print' class, its 'print' method knows how to deal with a '__FlashStringHelper *'. So, with proper casting, you can get the lcd object to do the reading into RAM for you.
Don't bother explaining that, I failed to do so one hour ago. http://forum.arduino.cc/index.php?topic=573782.0
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Dr_Quark

Don't bother explaining that, I failed to do so one hour ago. http://forum.arduino.cc/index.php?topic=573782.0
Posting 40 lines of code is not "explaining." Don't let your 7,000 posts convince you that you're a gift to clarity. I do appreciate the effort you put in, but it was over my head without accompanying text.
Dr.Quark

JMeller

Try this:
Code: [Select]

char apology[50];

void setup() {
  Serial.begin(115200);
  Serial.println("Booting...");
  memset(apology, '\0', sizeof(apology));
  strcat(apology,"Dear Whandall," );
  strcat(apology,"I apologize for " );
  strcat(apology,"acting like an " );
  strcat(apology,"arse." );
  Serial.println(apology);
  Serial.println("Complete.");
}

void loop() {
  // put your main code here, to run repeatedly:

}

Whandall

I feel showing how things can be done, should have some value for someone who struggles to accomplish it.

Sorry that I'm not the spoonfeeding type of person you seem to expect.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

westfw

#9
Oct 16, 2018, 10:22 am Last Edit: Oct 16, 2018, 10:23 am by westfw
Quote
I just need to learn how to read one substring at a time into a RAM string so I can lcd.print() it.
The obvious answer is to null terminate each string, at which point using flashStringHelper or other flash-to-ram copy functions becomes a lot easier.
Why did you want to get rid of the nulls?
Code: [Select]
const char TEXT[] PROGMEM = "Token1\0" // Comments
                            "Token2\0" // More comments
                            "Third0\0"
                            "Fourth\0"                         
                            "Last o\0"; // Yup, the end!

void setup() {
  Serial.begin(9600);
}

void loop() {
  char c = Serial.read();
  if (c > ' ') { // only listen to "real" characters.
    int whichToken = c & 7;  // strip off bits to make char a small int index.

    // Each token is 7 bytes (including the null), so an char index is 7 * the token index
    int whichChar = 7 * whichToken;

    // A flash string pointer is constructed by adding the char index to the start, and "casting."
    __FlashStringHelper *f = (__FlashStringHelper *) (TEXT + whichChar);
    Serial.println(f);
  }
}


(using "\0" puts nulls in the single string, instead of the issues you get with an array of character pointers that don't necessarilly point to flash.)


Go Up