Question

What are the differences between using scanf with the following format specifiers, when the input being scanned is 123456 versus when it's 123:

  • %6d
  • %-6d
  • %0d

What are the differences in the output?

Was it helpful?

Solution

I ended up just trying it with GCC 4.3.4, and got the following:

  • %6d: Works fine; only reads 6 characters (so if you try to read 123456789 it will only read 123456)
  • %-6d: Emits the warning:

    warning: unknown conversion type character '-' in format
    

    Doesn't read anything, and the int being written to is unmodified

  • %0d: Emits the warning:

    warning: zero width in scanf format
    

    Reads as though there were no width in the format specifier (%d)

I haven't checked the spec to see if those results are mandated or just how GCC handles it (EDIT: AndreyT found it)

OTHER TIPS

The %-6d is an invalid format specifier. There are no format specifiers with - in them in scanf.

In %6d the 6 part is called maximum field width. It works with all format specifiers (not only with d) and specifies the maximum number of characters to read before any format-specific conversion is performed. For example, if input sequence is 1234567, then %3d will read and convert 123 and %6d will read and convert 123456.

The %0d is an invalid format specifier. Maximum field width in scanf must be a non-zero integer (see 7.19.6.2/3 in the language specification).

So, that leaves us with %6d as the only meaningful format specifier among the three you provided. Under these circumstances the question about differences in output (in results?) makes little sense.

EDIT: One can probably argue that in %-6d the -6 part is the maximum field width, which satisfies the standard requirement of being non-zero decimal integer. However, in C language terminology a decimal integer as a lexical element is a sequence of digits and digits only. It is not allowed to include a sign. I.e. neither -6 nor +6 are decimal integers. Every time you use -6 or +6 as integers in your program it is actually unary - and + operator lexeme followed by decimal integer lexeme. So, since the specification of scanf requires a non-zero decimal integer as maximum field width, it must be a sign-less integer.

Here's what I think will happen: %6d will get you the first 6 digits of the number, %-6d will probably not work as you expect, since - is more of an output alignment specifier. %0d would mean you want only 0 characters, which would probably not work as expected.

Both %-6d and %0d are invalid conversion specifications for scanf, so the behavior for those cases will be undefined. See the language standard, § 7.19.6.2, ¶ 3.

I'll assume, like Arkadiy, that you really meant printf-style formatting, since you refer to "output". I'll also assume that you're using C (as the tag suggests).

If you run:

printf("%6d %-6d %0d", num1, num2);

...you'll end up with compiler errors (or, worse still, runtime bugs), as you haven't supplied enough arguments for three formats.

I've a feeling that that's not what you were asking, though. Let's assume that you actually run:

// (I've added some extra stuff to show how the formatting works.)
printf("'%6d'/'%-6d'/'%0d'", num2, num2, num2);

...you'll get:

'   123'/'123   '/'123'

Normally, if the field width (6 in this case) is wide enough, numbers are right-aligned, space-padded. If you put a '-' before the field width, they will be right-aligned, space-padded.

The subtlety here is in the "%0d" format. You might think you're specifying a zero-width field...and you'd be wrong. The first thing after the '%' is an option flag, and '0' is a valid flag. It means, "If the field width is wider than the content, left-pad with zeroes." In this case, you haven't supplied a field width (the '0' is a flag, remember?), so the '0' flag has no effect: the field will be as wide as the content requires.

There's an even worse subtlety, though. If you specified "%-06d", you'd get right-padding with zeroes, right? Um, no. The '-' flag overrides the '0' flag, whichever order they're supplied. You'd get '123   '.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top