tags:

views:

404

answers:

9

What is the use of "%n" format specifier in C. Could anyone explain with an example.

Thanks in advance.

+14  A: 
Starkey
@Starkey: Will give +1 if you add example code.
Merlyn Morgan-Graham
@Starkey: You mention that the argument must be a pointer to a signed int, then you used an unsigned int in your example (probably just a typo).
bta
Oops, you are right. Typo fixed. Thanks!
Starkey
+6  A: 

The argument associated with the %n will be treated as a int* and filled with the number of total characters printed at that point in the printf.

Evan Huddleston
+5  A: 

From here we see that it stores the number of characters printed so far.

%n Number of characters written by this printf.
No argument expected.

An example usage would be:

int n_chars = 0;
printf("Hello, World%n", &n_chars);

n_chars would then have a value of 12.

KLee1
+1  A: 

It doesn't print anything. It is used to figure out how many characters got printed before "%n" appeared in the format string, and output that to the provided int:

#include "stdio.h"

int main(int argc, char* argv[])
{
    int resultOfNSpecifier = 0;
    _set_printf_count_output(1); /* Required in visual studio */
    printf("Some format string%n\n", &resultOfNSpecifier);
    printf("Count of chars before the %%n: %d\n", resultOfNSpecifier);
    return 0;
}
Merlyn Morgan-Graham
+2  A: 

I haven't really seen many practical real world uses of the %n specifier, but I remember that it was used in oldschool printf vulnerabilities with a format string attack quite a while back.

Something that went like this

void authorizeUser( char * username, char * password){

    ...code here setting authorized to false...
    printf(username);

    if ( authorized ) {
         giveControl(username);
    }
}

where a malicious user could take advantage of the username parameter getting passed into printf as the format string and use a combination of %d %c or w/e to go through the call stack and then modify the variable authorized to a true value.

Yeah it's an esoteric use, but always useful to know when writing a daemon to avoid security holes? :D

http://en.wikipedia.org/wiki/Format_string_attack

Xzhsh
+1 I never actually heard about this.
Alexandre C.
printf(username) is asking for format string attack.
Nyan
Well yeah, that's the point :P
Xzhsh
+16  A: 

Most of these answers explain what %n does, but so far no one has really given an example of what use it has. Here is one:

int n;
printf("%s: %nFoo\n", "hello", &n);
printf("%*sBar\n", n, "");

will print:

hello: Foo
       Bar

with Foo and Bar aligned. (It's trivial to do that without using %n for this particular example, and in general one always could break up that first printf call:

int n = printf("%s: ", "hello");
printf("Foo\n");
printf("%*sBar\n", n, "");

Whether the slightly added convenience is worth using something esoteric like %n (and possibly introducing errors) is open to debate.)

jamesdlin
Oh my - this is a character-based version of computing the pixel size of string in a given font!
Arkadiy
+2  A: 

So far all the answers are about that %n does, but not why anyone would want it in the first place. I find it's somewhat useful with sprintf/snprintf, when you might need to later break up or modify the resulting string, since the value stored is an array index into the resulting string. This application is a lot more useful, however, with sscanf, especially since functions in the scanf family don't return the number of chars processed but the number of fields.

Another really lame use is getting a pseudo-log10 for free at the same time while printing a number as part of another operation.

R..
+1 for mentioning uses for `%n`, although I beg to differ about "all the answers...". =P
jamesdlin
A: 

%n is C99, works not with VC++.

`%n` existed in C89. It doesn't work with MSVC because Microsoft disabled it by default for security concerns; you must call `_set_printf_count_output` first to enable it. (See Merlyn Morgan-Graham's answer.)
jamesdlin
jamesdlin
A: 

It is supremely useful for hacking into poorly written daemons: http://julianor.tripod.com/bc/formatstring-1.2.pdf

Crashworks