Progmem() and memcpy()

I thought I understood address space and pointers, but I am lost. I've gone through 7-8 long threads about the topic and Nick Gammon's "Putting constant data into program memory (PROGMEM)" to no avail.

I need to put 50 10-char strings into program memory and then access them for printing to an LCD. My objective is to minimize RAM. I get the idea that something like the code fragments below is the basic concept, but I've tried every combination of asterisk (*) and ampersand (&) with my variable name(s) and nothing works, even with no compile errors. Plus, the pointer array "idtext" for 50 strings eats up 100 bytes.

char* const idtext PROGMEM = { // PROGMEM
"strng1",
"strng2",
"strng3" } ; // 21 bytes in memory

char buffer[11] ;

// faux code below, eg, move some characters from progmem to buffer
buffer = progmem(pointer, length)

I get the idea that

memcpy(pointer_1, pointer_2, length) or maybe memcpy_P(pointer_1, pointer_2, length)

should do what I want, but I have no idea how to make pointer_1 point into RAM (where buffer is) and pointer_2 point into program memory where the characters in idtext are.

It seems to me that if I know where idtext[0] is, then I know where all the strings are without needing any additional pointers. So really, I only want one pointer to the beginning of a 500-character string. If I can copy 10 bytes to buffer, I can append a null to make it a string for lcd.print().

const char string_1[] PROGMEM = "String 1";
const char string_2[] PROGMEM = "String 2";
const char string_3[] PROGMEM = "String 3";
const char string_4[] PROGMEM = "String 4";
const char string_5[] PROGMEM = "String 5";

const char * const string_table[] PROGMEM = {
  string_1,
  string_2,
  string_3,
  string_4,
  string_5
};

void setup() {
  Serial.begin(250000);
  char buffer[10];

  for (unsigned char i = 0; i < 5; i++) {
    strcpy_P(buffer, (PGM_P)pgm_read_word(&(string_table[i])));
    Serial.print(F("from buffer: '"));
    Serial.print(buffer);
    Serial.println(F("'"));
    Serial.print(F("directly: '"));
    Serial.print((__FlashStringHelper*)pgm_read_word(&(string_table[i])));
    Serial.println(F("'"));
  }
}

void loop() {}
from buffer: 'String 1'
directly: 'String 1'
from buffer: 'String 2'
directly: 'String 2'
from buffer: 'String 3'
directly: 'String 3'
from buffer: 'String 4'
directly: 'String 4'
from buffer: 'String 5'
directly: 'String 5'

Thanks, but this is a bit undecipherable for me.

If I you have

const char * const string_table PROGMEM = {
string_1,
...

then string_1 must be a pointer to the beginning of the 500-ish bytes of text in flash memory. There must be a way to provide a pointer that points to the [say 35th] string, read those 10 bytes into a RAM buffer, and then lcd.print() them.

Further, if you fill string_table with all the pointers and build all the variable pointer names, what benefit is that for all the ram you are using?

Dr_Quark:
then string_1 must be a pointer to the beginning of the 500-ish bytes of text in flash memory.

string_1 is a char array in PROGMEM, an so its name is a constant pointer.

Dr_Quark:
There must be a way to provide a pointer that points to the [say 35th] string, read those 10 bytes into a RAM buffer, and then lcd.print() them.

My example does exactly that (on Serial) for the 5 strings in the table.
And it shows how to print them without RAM copy.

Dr_Quark:
Further, if you fill string_table with all the pointers and build all the variable pointer names, what benefit is that for all the ram you are using?

Neither the table of pointers nor the strings take any RAM.

Dr_Quark:
I need to put 50 10-char strings into program memory and then access them for printing to an LCD.

const char strings[50][14] PROGMEM = {"First String", "Second String", "Third String", ... "50th String"};
lcd.print((__FlashStringHelper*)&strings[27]);  // Display the 28th string

Note: Be sure to leave enough room in your array elements for the longest string plus a null terminator. Just turn up your warning level to "ALL" and increase the size until you stop getting"warning: initializer-string for array of chars is too long [-fpermissive]" messages.