sprintf with prog_char

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am trying to use sprintf, well likely snprintf, with some strings that are in flash

code
sprintf(buff, "var = d string = s\n", my_int, string_in_rom)

.... Why can't I use a % sign in the code block?

Anyway, int is a variable in RAM while the string is pointed to by a prog_char *.

So far I cannot get this to work. If I use sprintf or snprintf I can get the RAM int to print but not the string. If I use s[n]printf_P I do not get either value.

Also, I do not get any warnings, errors or anything else that would suggest this does not work. I am using -Wall to the best of my knowledge (not my make file originally). Should the above produce a waring or error.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

.... Why can't I use a % sign in the code block?

When posting? It's a matter of the security set at a very high level at this site, after some nasty attacks in recent years.

The regulars have learned to live with it and replace the percent-sign with something else and attach instructions to eg "replace
with the percent-character".

As to your problem, you cant send a PROGMEM variable directly to eg sprintf. The variable has to be read out of flash and into RAM, and that then used as a parameter.

Go over to the Tutorials forum and look up the tutorial on PROGMEM, by Dean Camera (known as 'abcminiuser' here at AVRfreaks). Excellent stuff, and a must read of youre using PROGMEM and friends.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So I need to copy the progmem string to RAM before use? OK, I thought that the _P variant of sprintf accepted those types of arguments. I was then trying to figure out if the _P could accept both regular and progmem addresses. Looking in a bit more I see that _P simply means ONLY the format string "....
s....." is in progmem.

Swing and a miss for me. Thankfully I have lots of time to learn about this stuff as there is a blizzard warning till noon tomorrow so no class till Thursday.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

To be clear, there is a distinction to be made between situations where the (1) format string itself lives in Flash, and (2) situations where one of the additional parameters passed in after the format string, is a pointer to a string that lives in Flash.

(1) For the first case, where the format string lives in Flash, avr-libc offers a nonstandard extension in the form of the *printf_P family of functions. But when using those functions, you still have to go out of your way to ensure that the format string is located correctly.

(2) For the second case, you could do as Johan suggests, and copy the Flash string into RAM before calling printf. Alternatively, avr-libc offers another non-standard extension, to the format specifiers interpreted by printf. This extension allows you to pass in a pointer to a string in Flash. Instead of
s (lower-case s), use
S (capital S).

The lower-case s refers to a string in RAM, and an upper-case S refers to a string in (the lower 64K of) Flash. If you don't know (at the time the format string is generated) whether the string you're dealing with lives in Flash or RAM, you're out of luck.

- Luke