SergeantPenguin SergeantPenguin - 1 month ago 16
C Question

Forcing printf to ignore formatting

I'm using the pdcurses library and I'm writing a function which moves a line on the screen up one. This involves copying the current line and then pasting it above. The problem is that the curses function for printing whole lines,

printw
, uses the same format strings as
printf
. These lines could contain percentage signs, and so once pasted those signs are of course lost.


The printw() functions add a formatted string to the window at
the current or specified cursor position. The format strings are
the same as used in the standard C library's printf(). (printw()
can be used as a drop-in replacement for printf().)


A small example would be:

chtype p[200];
winchnstr(w, p, 200); //obtain the line
clrtoeol(); //remove the line

wmove(w, y-1, x); //move up a line
clrtoeol(); //erase the line
wprintw(w, p); //print the new line


Is there any way to force printf to treat the percentage signs as normal without having to go through
p
and inserting a percentage sign between every one? That seems a rather annoying for something so simple.

The first solution would be to convert
p
to a string, iterate through the string, and insert a
%
behind every
%
. But when I moving lots of lines at once (I'm trying to create an effect of the screen moving "upwards") this might not be the best solution performance-wise, would it?

The other solution would instead iterate through
p
and just use
addch()
to add each character separately. But would this lose performance/efficiency in comparison to
wprintw
? Or is
wprintw
simply a glorified version of just pasting each character individually? Are these really the only two options I have?

Answer

To force printf to accept your string as it is, use the format specifier %s and pass your string as an argument. printf arguments are not subject for format processing. In case of strings, the bytes are simply copied over to the destination buffer.

printf("%s", "My string with % signs");

In case your string isn't zero-terminated, you can pass a length before the string to printf if you use the %*s format specifier:

printf("%*s", 5, "ab%cdefghi"); // prints "ab%cd"

Note that the length argument must be of type int.

Comments