josh
josh

Reputation: 14463

What is the use of the %n format specifier in C?

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

Upvotes: 166

Views: 143274

Answers (13)

Zoltan K.
Zoltan K.

Reputation: 1200

Here is another example, when you would want to use it:

inp="1bla";

sscanf(inp, "%d%n", &val, &cnt);
if (cnt == strlen(inp)) {
    // the whole "inp" was consumed
} else {
    // there is some garbage at the end of "inp"
}

Upvotes: 0

the kamilz
the kamilz

Reputation: 1988

Those who want to use %n Format Specifier may want to look at this:

Do Not Use the "%n" Format String Specifier

In C, use of the "%n" format specification in printf() and sprintf() type functions can change memory values. Inappropriate design/implementation of these formats can lead to a vulnerability generated by changes in memory content. Many format vulnerabilities, particularly those with specifiers other than "%n", lead to traditional failures such as segmentation fault. The "%n" specifier has generated more damaging vulnerabilities. The "%n" vulnerabilities may have secondary impacts, since they can also be a significant consumer of computing and networking resources because large guantities of data may have to be transferred to generate the desired pointer value for the exploit. Avoid using the "%n" format specifier. Use other means to accomplish your purpose.

Source: link

Upvotes: 1

Md Adnan Kabir
Md Adnan Kabir

Reputation: 1

In my opinion, %n in 1st argument of print function simply record the number of character it prints on the screen before it reach the the %n format code including white spaces and new line character.`

#include <stdio.h>

int main()
{
    int i;
    printf("%d %f\n%n", 100, 123.23, &i);
    printf("%d'th characters printed on the screen before '%%n'", i);
}

output: 100 123.230000

15'th characters printed on the screen before '%n'(with new character).

We can assign the of i in an another way...

As we know the argument of print function:-

int printf(char *control-string, ...);

So, it returns the number the number of characters output. We can assign that return value to i.

#include <stdio.h>

int main()
{
    int i;
    i = printf("%d %f\n", 100, 123.23);
    printf("%d'th characters printed on the screen.", i);
}

Upvotes: 0

Evan
Evan

Reputation: 756

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

Upvotes: 13

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215617

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 hackish use is getting a pseudo-log10 for free at the same time while printing a number as part of another operation.

Upvotes: 15

jamesdlin
jamesdlin

Reputation: 90174

The other day I found myself in a situation where %n would nicely solve my problem. Unlike my earlier answer, in this case, I cannot devise a good alternative.

I have a GUI control that displays some specified text. This control can display part of that text in bold (or in italics, or underlined, etc.), and I can specify which part by specifying starting and ending character indices.

In my case, I am generating the text to the control with snprintf, and I'd like one of the substitutions to be made bold. Finding the starting and ending indices to this substitution is non-trivial because:

  • The string contains multiple substitutions, and one of the substitutions is arbitrary, user-specified text. This means that doing a textual search for the substitution I care about is potentially ambiguous.

  • The format string might be localized, and it might use the $ POSIX extension for positional format specifiers. Therefore searching the original format string for the format specifiers themselves is non-trivial.

  • The localization aspect also means that I cannot easily break up the format string into multiple calls to snprintf.

Therefore the most straightforward way to find the indices around a particular substitution would be to do:

char buf[256];
int start;
int end;

snprintf(buf, sizeof buf,
         "blah blah %s %f yada yada %n%s%n yakety yak",
         someUserSpecifiedString,
         someFloat,
         &start, boldString, &end);
control->set_text(buf);
control->set_bold(start, end);

Upvotes: 17

Starkey
Starkey

Reputation: 9781

Nothing printed. The argument must be a pointer to a signed int, where the number of characters written so far is stored.

#include <stdio.h>

int main()
{
  int val;

  printf("blah %n blah\n", &val);

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

  return 0;

}

The previous code prints:

blah  blah
val = 5

Upvotes: 170

Sudhanshu Mishra
Sudhanshu Mishra

Reputation: 2092

It will store value of number of characters printed so far in that printf() function.

Example:

int a;
printf("Hello World %n \n", &a);
printf("Characters printed so far = %d",a);

The output of this program will be

Hello World
Characters printed so far = 12

Upvotes: 1

Merlyn Morgan-Graham
Merlyn Morgan-Graham

Reputation: 59151

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;
}

(Documentation for _set_printf_count_output)

Upvotes: 2

Xzhsh
Xzhsh

Reputation: 2239

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

Upvotes: 21

KLee1
KLee1

Reputation: 6178

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

n The argument shall be a pointer to an integer into which is written the number of bytes written to the output so far by this call to one of the fprintf() functions. No argument is converted.

An example usage would be:

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

n_chars would then have a value of 12.

Upvotes: 14

jamesdlin
jamesdlin

Reputation: 90174

Most of these answers explain what %n does (which is to print nothing and to write the number of characters printed thus far to an int variable), 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.)

Upvotes: 248

user411313
user411313

Reputation: 3990

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

Upvotes: -6

Related Questions