progmem confusion

OK, I'm lost. How would I modify this code so that both the format string and the string "Hello" are in progmem.

char buffer[16];

void addToBuff(const char* disp){
  int a =10;
  sprintf(buffer, "%d%s%n", a, disp);
}

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

void loop(){
  
  addToBuff("Hello");
  
  Serial.println(buffer);
  
  delay(1000);
  
}

Well, to start with, you'd have to find a version of sprintf() that supported progmem strings. :frowning: (I don't think that one exists.)
The addition of the F() macro to Arduino's print() functions gave it a big advantage over traditional printf(). Since printf is a C function, it can't tell the difference between flash and ram pointers.

westfw:
Well, to start with, you'd have to find a version of sprintf() that supported progmem strings. :frowning: (I don't think that one exists.)

There actually is one...
http://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html#ga53ff61856759709eeceae10aaa10a0a3

(I highly recommend using the n-version (snprintf_P vs sprintf_P).)

That would let me use the F macro on my format string?

What about the other constant string. The one I'm passing around as a variable. I don't mind pulling them out and copying them to SRAM in the original caller just for the time that they're needed so I can pass them around as regular char*, but I have a lot of strings here and they can't all be hanging out in the heap together while they're not being used.

I've passed things around using the F() macro before by having the called function take a __FlashStringHelper. That works great if you're sending it out Serial or something that takes a __FlashStringHelper, but as far as I can tell I can't use that with sprintf.

sprintf_P(s, PSTR("%d%S%n"), a, disp);

Note capital S in the format string...

I may have solved my own problem here. If I go and derive the display class that I'm having trouble passing these to so that it derives from print then all I have to do is write code to put characters in the buffer (the virtual write method) and the print class will know what to do with the rest.

#include <avr/pgmspace.h>
char buffer[16];


void addToBuff(prog_char* disp){
  int a =10;
  char insideBuf[10];
  strcpy_P (insideBuf, disp);
  sprintf_P(buffer, PSTR("%d%s%n"), a, insideBuf);
}

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

void loop(){
  
  addToBuff(PSTR("Hello"));
  
  Serial.println(buffer);
  
  delay(1000);
  
}

This appears to do what I want. I can't find any way to get sprintf or sprintf_P to take a variable that is in progmem, but I don't mind the temporary buffer and the call to strcpy_P.

I think I still might see what happens if I derive my class from print and use F instead of PSTR. Would there be any advantage? This is done, I guess that makes it easier by default.