How Many Characters Output – So Far?

I doubt any C programmer has memorized all of the printf() function’s placeholders, options, and settings. It’s a character salad of interesting and weird things. One of the strangest has to be the %n placeholder.

For a placeholder review, refer to my series of Lessons on Conversion Character Mania, which starts here.

From last week’s Lesson, the printf() function returns the number of characters output. The %n placeholder, used within the format string, returns the number of characters output so far.

Suppose that the format string is "123%n456". If so, the %n placeholder represents the value three, the number of characters output before its position in the string. The value reflects output, so another placeholder appearing before %n affects the value returned.

To make the %n placeholder work, its corresponding argument must be the address of an int value. The following code demonstrates:

2022_03_05-Lesson-a.c

#include <stdio.h>

int main()
{
    int n;

    printf("Oh no!%n Here comes Godzilla!\n",&n);
    printf("%d\n",n);

    return(0);
}

Integer variable n is declared at Line 5. Its address is referenced in the printf() statement at Line 7. The value stored is the number of characters output before the %n placeholder appears (most likely six).

At Line 8, the value of variable n is output.

Here’s a sample run:

Oh no! Here comes Godzilla!
6

Yup. It’s six.

The disappointing news is that you cannot access this value until after the printf() statement returns. So the following code doesn’t do what you think it does:

2022_03_05-Lesson-b.c

#include <stdio.h>

int main()
{
    int n;

    printf("The total is %d!%n\n%d characters output above\n",
            500*80,
            &n,
            n
          );

    return(0);
}

The %n placeholder appears after the exclamation point in the printf() format string at Line 7. Its argument appears at Line 9, but the value is used at Line 10. This value is unset, as the output proves:

The total is 40000!
24342624 characters output above

The number 24342624 represents whatever garbage is in memory before variable n is initialized. That’s because the value is initialized after the function returns.

Add the following statement at Line 12:

printf("n==%d\n",n);

Save, build, and run to see this output:

The total is 40000!
24342624 characters output above
n==19

Seeing how the %n placeholder’s value isn’t available until after the function executes makes this placeholder seem less-than-useful to me. While you could use this value and the printf() function’s return value to do some character output math, the %n placeholder does have a warning attached to it.

It’s possible that the %n placeholder can be used to nefariously write data to a sensitive memory location. The method is complex, but the format string can be manipulated in a way to access memory in a malicious manner. Even for secure functions such as snprintf(), avoid using a string variable to set the format string when the %n placeholder is used.

I believe the warning about the %n placeholder outweighs any useful value it may have, though I remain curious which type of code would require this placeholder in the first place.

2 thoughts on “How Many Characters Output – So Far?

  1. I have some vague idea that you could use this with sprintf to decide whether to output the resulting string as-is, or whether to truncate it or split it over more than one line if it’s too long.

Leave a Reply