Reputation: 575
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?
Upvotes: 1
Views: 16791
Reputation: 320719
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.
Upvotes: 6
Reputation: 141
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 '.
Upvotes: 0
Reputation: 123578
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.
Upvotes: 0
Reputation: 175695
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)
Upvotes: 5
Reputation: 5211
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.
Upvotes: 1