Why % gets printed in half count in C? - c

#include<stdio.h>
main()
{
printf("% % % %");
}
For the above program, the output is % %. But why? (I used gcc compiler).

Undefined behavior is invoked by using invalid format specifier.
N1570 7.21.6.1 The fprintf function says in the description of % conversion specifier:
The complete conversion specification shall be %%.
N1570 4. Conformance says:
If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint or runtime-constraint is violated, the behavior is undefined.
The description of % conversion specifier is in "Description" section, not constraint nor runtime-constraint section.
In the actual implemention, the system's behavior seems like this:
Read first % and start parsing specifier
Read and save it as a flag
Read second % and treat it as % conversion specifier
Read after that and print it because it is not a part of specifier
Read % % and do work like 1-3

That is interesting. the % % counts as %% somehow, huh. Must be in the parsing rules for printf formats in the stdio library. In general "% " is not exactly a valid format specification. %% %% %% %% would get you what you want.

Related

Can anyone explain the output printf("%0 %x",a);?

This code is making me so confused. I can't understand what %0 is doing inside printf!
Code:
#include <stdio.h>
int main() {
int a = 100;
printf("%0 %x", a);
return 0;
}
Output
%x
%0 %x has an invalid printf conversion specification:
the 0 is a flag specifying that the number representation should be padded with initial zeroes to the specified width (which is not specified here)
the is a flag specifying that the signed conversion should be prefixed with a space if positive in the same place as a - for negative numbers.
the second % is the conversion specifier, so the initial part is just a variation of %% with 2 extra flags and thus should cause a % character to be output, but the C Standard specifies in 7.21.6.20 the fprintf function that
%: A % character is written. No argument is converted. The complete conversion specification shall be %%.
Hence %0 % is an invalid conversion specification as % does not accept flags.
Most libraries will just output %x, ie: % for %0 % and x for the trailing x, ignoring the a argument, and this is what you get on your system, but the behavior is actually undefined, so nothing can be assumed.
Conversely, printf("|%0 5d|", 100); will output | 0100| but the space is ignored for the x conversion which is unsigned so printf("|%0 5x|", 100); will output |00064|.

Why only multiple "%" is accepted by printf?

Following program give the output %%. Why?
#include <stdio.h>
int main() {
//code
printf("%%%%");
return 0;
}
output:
%%
TL;DR a % is a valid conversion specifier for printf().
Quoting C11, chapter §7.21.6.1, for conversion specifiers,
Each conversion specification is introduced by the character %. After the %, the following
appear in sequence:
.....
— A conversion specifier character that specifies the type of conversion to be applied.
and, from paragraph 8, for % as a conversion specifier character
for % conversion specifier
% A % character is written. No argument is converted. The complete
conversion specification shall be %%.
Your code has a pair of %%s.
Printf function's first argument is a format represented by a char*, it's not a string.
That's why for printing an int,for example, you have to write "%d". So % is a special character, if you only write % as format, the compiler won't be happy because it is waiting for something after the % (either d, p, x, s, f, ...).
However, by writing %% it means "Print me one escaped %". That's why %%%% prints %%
EDIT: If you want a function that prints exactly what you give, you can use write:
char* mystr = "%%%%";
write(STDOUT_FILENO, mystr, strlen(mystr));

What does a # sign after a % sign in a scanf() function mean?

What does the following code mean,in C
scanf("%d%#d%d",&a,&b,&c);
if given values 1 2 3 it gives output as 1 0 0
P.S- I know it is used with printf() statement but here in scanf() statement it gives random behaviour.
TL;DR; - A # after a % sign in the format string of scanf() function is wrong code.
Explanation:
The # here is a flag character, which is allowed in fprintf() and family, not in fscanf() and family.
In case of your code, the presence of # after % is treated as invalid conversion specifier. As per 7.21.6.2,
If a conversion specification is invalid, the behavior is undefined
So, your code produces undefined behaviour.
Hint: you can check the return value of scanf() to check how many elements were "scanned" successfully.
However, FWIW, using # with %d in printf() also is undefined behaviour.
Just for reference: As per the C11 standard document , chapter §7.21.6.1, flag characters part, (emphasis mine)
#
The result is converted to an ‘‘alternative form’’. For o conversion, it increases the precision, if and only if necessary, to force the first digit of the result to be a zero (if the value and precision are both 0, a single 0 is printed). For x (or X) conversion, a nonzero result has 0x (or 0X) prefixed to it. For a, A, e, E, f, F, g, and G conversions, the result of converting a floating-point number always contains a decimal-point character, even if no digits follow it. (Normally, a decimal-point character appears in the result of these conversions only if a digit follows it.) For g and G conversions, trailing zeros are not removed from the
result. For other conversions, the behavior is undefined.
According to the Standard, the use of # is illegal.
Its use makes your program invoke Undefined Behaviour.
Of course, if your implementation defines it, it is defined behaviour for your implementation and it does what your documentation says.

understanding weird output of printf function

According to me
int a=0;
printf("%d",a);
works same as
char *ptr="%d"
ptr points to % and then ptr reads the whole string from % and 4 bytes are read from memory.
Now consider the below code
printf("%d"+1,a); //value of a=0
is same as
char *ptr="%d"
ptr+=1;
ptr now points to d and so string from d is printed
Now
printf(1+"Alex"); //prints lex
ptr points l and prints string from there on....
Now what will happen in the following cases?It appears to be out of my scope.
printf("%",a);
printf("%%%%");
printf("%%d",a);
printf("%",a); does not have a valid conversion specifier, so it is covered by:
§7.21.6.1
9 If a conversion specification is invalid, the behavior is
undefined. If any argument is not the correct type for the
corresponding conversion specification, the behavior is undefined.
printf("%%%%"); will simply print %%, since %% is a conversion specifier. See the printf man pages.
%
A '%' is written. No argument is converted. The complete conversion
specification is '%%'.
As mentioned in the comments, printf("%%d",a); is probably not undefined behavior. %% becomes % and the a is ignored.
§7.21.6.1
2 The fprintf function writes output to the stream pointed to by stream,
under control of the string pointed to by format that specifies how
subsequent arguments are converted for output. If there are
insufficient arguments for the format, the behavior is undefined. If
the format is exhausted while arguments remain, the excess arguments
are evaluated (as always) but are otherwise ignored. The fprintf
function returns when the end of the format string is encountered.
I hope that this quote from the C Standard will help you
8 The conversion specifiers and their meanings are:
% A % character is written. No argument is converted. The complete
conversion specification shall be %%.
For example
printf("%%%%");
will output
%%

What will be Output in C?

I ran the following code segment in C:
printf("%%%\n");
I got the output "%" (without quotes). Can anyone explain what exactly happened?
Why we got only one % sign in result?
%% will print %. %\n is not a valid conversion specifier.
You should always enable warnings. See the following:
warning: unknown conversion type character 0xa in format [-Wformat=]
printf("%\n");
^
As noted in the comments, this is undefined behavior because according to the C11 standard, it is undefined behavior if:
— An invalid conversion specification is found in the format for one of the formatted input/ouptut functions [...]

Resources