Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the behavior when a printf specifier flag is repeated?

fprintf() family of functions have 5 flag characters '-', '+', ' ', '#', '0'.

What is the specified behavior, if any, when a flag is repeated?

#include <stdio.h>
int main(void) {
  printf("%  d\n", 12);     //  12
  printf("%00d\n", 34);     // 34
  printf("%++d\n", 56);     // +56
  printf("%00*d\n", 5, 78); // 00078
  return 0;
}

With my gcc "i686-pc-cygwin/4.9.2" I receive "warning: repeated ' ' flag in format [-Wformat=]", so I assume this is a correct behavior--> warn user and allow repeated flag.

I have yet to find a C99/C11 specification guidance for this corner issue found while trying to write a format parser.

If repeating allowed, the following code is OK. If repeating is not allowed, the 2nd 0 is the width. Then the specifier has 2 widths 0 and *, which is another problem.

// -------v
printf("%00*d\n", 5, 78); // 00078
like image 344
chux - Reinstate Monica Avatar asked Apr 13 '15 17:04

chux - Reinstate Monica


People also ask

What is the purpose of the flag in printf function?

The printf() conversion flags are enabled by specifying one or more of the following characters, which may appear in any order: ' The integer portion of the result of a decimal conversion (%i, %d, %u, %f, %g, or %G) is formatted with thousands grouping characters using the non-monetary grouping character.

What is %B in printf?

The Printf module API details the type conversion flags, among them: %B: convert a boolean argument to the string true or false %b: convert a boolean argument (deprecated; do not use in new programs).


2 Answers

In my opinion, the standard is unclear on this point.

The authors of gcc were clearly of the opinion that repeated flags are invalid, since gcc issues a warning by default for something like:

printf("%++d\n", 42);

but that doesn't necessarily tell us what the authors of the standard intended.

The standard permits:

Zero or more flags (in any order) that modify the meaning of the conversion specification.

The flags are -, +, space, #, and 0. The phrase "Zero or more flags* is, I think, specifically intended to permit different flags to be combined. For example, this:

#include <stdio.h>
int main(void) {
    printf("|%6x|\n", 0x123);
    printf("|%-6x|\n", 0x123);
    printf("|%#6x|\n", 0x123);
    printf("|%-#6x|\n", 0x123);
    printf("|%#-6x|\n", 0x123);
}

is valid and produces this output:

|   123|
|123   |
| 0x123|
|0x123 |
|0x123 |

In other contexts, the standard is explicit about whether a construct may or may not be repeated. For example, long long int is distinct from long int, and long int int is a syntax error. On the other hand, the standard explicitly says (N1570 6.7.3p5) that:

If the same qualifier appears more than once in the same specifier-qualifier-list, either directly or via one or more typedefs, the behavior is the same as if it appeared only once.

The lack of any such statement here makes me suspect that the authors of the standard didn't consider the case of repeating the same flag.

If I'm incorrect about this, and the committee did intend a repeated flag to be equivalent to a single flag, then your format parser should treat them as equivalent. If I'm correct, then the behavior of repeating the same flag is undefined, and your implementation can do anything you like -- including treating them as equivalent to a single flag.

In either case, you're free to issue a warning if you like. Even if the standard defines the behavior of a repeated flag, it's still arguably poor style and worth warning about.

like image 165
Keith Thompson Avatar answered Oct 02 '22 14:10

Keith Thompson


In the C standard (7.21.6.1 The fprintf function) there is written only that

4 Each conversion specification is introduced by the character %. After the %, the following appear in sequence:

Zero or more flags (in any order) that modify the meaning of the conversion specification.

So I suppose that flags may be repeated. Otherwise there would be some restrictions.

like image 44
Vlad from Moscow Avatar answered Oct 02 '22 13:10

Vlad from Moscow