What will be Output in C? - 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 [...]

Related

Why % gets printed in half count in 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.

C 's format specifier

I have this code in C-
#include <stdio.h>
void main(void)
{
int a=90;
float b=4;
printf("%f",90%4);
}
It gives an output 0.0000,I am unable to understand why???
i know that 90%4 returns 2 and the format specifier specified is %f,which is for double,but what I expect is-
That it will give an error,but it is showing 0.0000 as output.
Can someone please explain why?
The type of 90%4 will be int.
The behaviour on using %f as the format specifier for an int is undefined.
The output could be 2, it could be 0. The compiler could even eat your cat.
This discrepancy comes about because the compiler and library do not communicate regarding types. What happens is that your C compiler observes that printf is a variadic function taking any number of arguments, so the extra arguments get passed per their individual types. If you're lucky, it also parses the format string and warns you that the type doesn't match:
$ gcc -Wformat -o fmterr fmterr.c
fmterr.c: In function ‘main’:
fmterr.c:6:2: warning: format ‘%f’ expects argument of type ‘double’,
but argument 2 has type ‘int’ [-Wformat=]
printf("%f",90%4);
^
But this is still just a warning; you might have replaced printf with a function with different behaviour, as far as the compiler is concerned. At run time, floating point and integer arguments may not even be placed in the same place, and certainly don't have the same format, so the particular result of 0.0 is not guaranteed. What really happens may be related to the platform ABI. You can get specified behaviour by changing the printf argument to something like (float)(90%4).
printf is a variadic function. Such functions are obscure, with no type safety worth mentioning. What such functions do is to implicitly promote small integer types to type int and float to double, but that is it. It is not able to do more subtle things like integer to float conversion.
So printf in itself can't tell what you passed on it, it relies on the programmer to specify the correct type. Integer literals such as 90 are of type int. With the %f specifier you told printf that you passed a double, but actually passed an int, so you invoke undefined behavior. Meaning that anything can happen: incorrect prints, correct prints, program crash etc.
An explicit cast (double)(90%4) will solve the problem.
%f expects a double and you pass int(90%4=2) in printf. Thus ,leading to Undefined Behaiour and can give output anything .
You need to explicitly cast -
printf("%f",(double)(90%4));
Don't try this as compiler will generate an error (as pointed by #chux Sir )-
printf("%f",90%(double)4);
In short: there is no error checking for format specifiers. If your format is looking for a double, then whatever you pass as an argument (or even if you pass nothing) will be interpreted as a double.
By default, 90%4 gives an integer.
If you print integer with %f specifier, it will print 0.
For example, printf("%f", 2); will print 0.
You typecast result with float, you will get 2.00000.
printf("%f",(float) (90%4)); will print 2.00000
Hope it clarifies.

Why printf("%.1f", 1) output 0.0

I use the codeblock.
when the code is:
printf("%.1f", 1);
The program can run,and the output is 0.0. I want to know why.
`
Change it to:
printf("%.1f", 1.0);
f conversion specifier requires an argument of type double but you are passing an int value (1 is of type int). Passing an argument of the wrong type to printf invokes undefined behavior.
Using wrong format specifier invokes undefined behavior. You may get either expected or unexpected result. Use %d instead as the argument passed to printf is int type or change 1 to 1.0 if you are using %f.
C11: 7.21.6 (p9):
If a conversion specification is invalid, the behavior is undefined.282) If any argument is
not the correct type for the corresponding conversion specification, the behavior is
undefined.
The format is incorrect , you should give a float or a double as the second argument to the printf function. The gcc compiler also gives a warning on such mistakes by programmers.
printf("%.1f",1.23);
Output:
1.2
Be carefull with these kind of mistakes. Good luck!

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
%%

Is printf("%d", 1.0) undefined?

According to section 4.9.6.1 of the C89 draft, %d is a character that specifies the type of conversion to be applied.
The word conversion implies, in my opinion, that printf("%d", 1.0) is defined.
Please confirm or refute this.
The conversion is the conversion of a language value to a lexical representation of that value.
Your theory is wrong; behavior is undefined. The spec says (7.19.6.1p8 and 9, using C99 TC2):
The int argument is converted to signed decimal in the style [−]dddd.
And
If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
Printf is a varargs function, so no conversion is possible. The compiler just arranges to push a double onto the arguments list. Printf has no way to find out that it's a double versus an int versus an elephant. Result? Chaos.
The word "conversion" here is referring to the conversion of an int (which is the only acceptable argument type here) to a string of characters that make of the decimal representation of that int. It has nothing to do with conversion from other types (such as double) to int.
Not sure if it's officially undefined or an error - but it's wrong!

Resources