Get "substring" of a PROGMEM char array

Hello

I have a char array stored in progmem and would like to get a portion of the array to print to an LCD.
I have a function that takes the char array and and integer that determines where the substring would start.
However I cannot get it to work!
Any ideas?

const char PROGMEM testString[] = "big long string containing lots of characters";

void printSub(char charArray[], int start) {
  char buf[20];
  strncpy_P(buf, charArray[start], 20);
  lcd.print(buf);
  
}

void setup() {
   lcd.setCursor(0,0);
   printSub(testString, 13);
}

(I left out the lcd initialization code and loop() function on purpose)

and how about ?strncpy_P(buf, charArray[] + start, 20);

Deva_Rishi:
and how about ?strncpy_P(buf, charArray[] + start, 20);

Hello,
Thanks for the fast reply

When I do that I get this error:

/tmp/699981680/sketch_mar9a/sketch_mar9a.ino: In function 'void printSub(char*, int)':

/tmp/699981680/sketch_mar9a/sketch_mar9a.ino:15:28: error: expected primary-expression before ']' token

strncpy_P(buf, charArray[] + start, 20);

^

exit status 1

and with strncpy_P(buf, charArray + start, 20); ? I don't use strncpy_p myself but normally just use pgm_read_byte_near(charArray+start);and read the bytes individually.

Deva_Rishi:
and with strncpy_P(buf, charArray + start, 20); ?

Thanks, that works perfectly, except I also had to add a null terminator like so:

void printSub(char charArray[], int start) {
  char buf[21];
  strncpy_P(buf, charArray + start, 20);
  buf[20] = "\0";
  lcd.print(buf);
}

or else the lcd prints a couple random characters at the end

Thanks for the help!

You start with a 'const' char string, then you better use 'const' down the line, for example in the parameter of the function.
The strncpy_P does not add a zero-terminator when the source is truncated. Even the lcd.print must have a zero-terminated string.
The Arduino reference prefers to put 'PROGMEM' behind the variable name.
Deva_Rishi made a small mistake, the should be removed.
I like a pointer as parameter more than a array, allthough for the compiler it is the same thing.

That combined gives this:

// Arduino IDE 1.8.12
// Arduino Uno
//
// The 'PROGMEM' is placed behind the variabale name here:
// https://www.arduino.cc/reference/en/language/variables/utilities/progmem/
//
// When a string is uses as a parameter (with lcd.print or Serial.println),
// then it must be a zero-terminated string.
// The strncpy() does not guarantee a zero-terminator when the source is truncated:
// http://www.cplusplus.com/reference/cstring/strncpy/
//

const char testString[] PROGMEM = "big long string containing lots of characters";

void printSub( const char *p, int start)
{
  char buf[21];
  strncpy_P( buf, p + start, 20);
  buf[20] = '\0';   // make it a valid zero-terminated string
  Serial.println( buf);
}

void setup() 
{
  Serial.begin( 9600);
  printSub(testString, 13);
}

void loop() {}

@hypercubed, I was typing this post, but you have already fixed the problem. I will still show it to confirm that you are on the right track. buf[20] should be the character '\0', not the string "\0".

buf[20] should be the character '\0', not the string "\0".

Oh definitely ! You can hardly expect the compiler to optimize out the use of a whole class.