I have read that the type of string literal is char[n+1], where n is the length.The storage of string literals is an implementation issue.But still it must be unique at an instant.
printf
("%u\t %s\t %d\t %c\t %f\t %e\t %x\t %p\t",
&"XY",&"XY",&"XY",&"XY",&"XY",&"XY",&"XY",&"XY");
The output of this code is
4206628 XY 4206628 $ 0.000000 1.800980e-307 7ffde000 00000032
Why %f gives zero, %s gives XY (no effect of &?), and %p gives a totally different value?
You cannot pass values of the wrong type (a type that doesn't match what the formatting specifier says is expected) and not get undefined behavior.
For instance, it's quite possible that a double which is what %f expects is bigger than a pointer (which is what you're actually) passing, thus leading to a mis-match between the passed values and the values consumed by printf(), and more or less mayhem as a result.
Why %f gives zero?
Because %f expects a double while it's not, this leads to undefined behavior.
%s gives XY (no effect of &?)
Possibly because for an array arr: arr and &arr have the same value. However, the type is different, which means you are passing the unexpected type to printf, again, undefined behavior.
and %p gives a totally different value?
That's the pointer value you are looking for.
Related
The output of below program is confusing.
uint16_t first = 10, second = 20, third = 30;
// printf("%p\n", &first);
scanf("%d", &second); // "%d" used intentionally.
printf("%" SCNu16 " ", first);
printf("%" SCNu16 " ", second);
printf("%" SCNu16 "\n", third);
With first printf commented I get 10 20 0. (The "%d" in scanf might be causing this. It works fine if I use "%" SCNu16 in place of %d).
With first printf uncommented I get 0 20 30.
Confusion is - why is printf causing the difference in output? This is a consistent behavior.
In your code,
scanf("%d", &second);
is undefined behavior. %d expects the argument to be a pointer to a signed integer type (int).
Quoting C11, chapter §7.21.6.2, fscanf function
[...] Unless assignment suppression was indicated by a *, the
result of the conversion is placed in the object pointed to by the first argument following
the format argument that has not already received a conversion result. If this object
does not have an appropriate type, or if the result of the conversion cannot be represented
in the object, the behavior is undefined.
That said, SCNuN macro is for fscanf family, fprintf() family has the counterpart as PRIuN.
If it is a "consistent behavior" or not depends on your definition of it. I get the same behavior when I run your code, but it does not change the fact that you have undefined behavior in your program.
I tried compiling it with -O3 and then I got the output 10 20 30 when giving the input 20, both with and without the said printf statement.
So while it could be fun to speculate about why your code behaves the way it does, it is not very meaningful. The code is invalid, so you have no guarantees.
I also tried switching the order of variable declaration: uint16_t third=30, second=20, first=10; The behavior changed, although it should not if the code were valid.
I got a problem with printf the pointer address. I was confused with printf.Here is the code:
#include<stdio.h>
int main() {
float aa[3] = {1.0, 2.0, 3.0};
printf("%f, %f\n", aa, aa[1]);
return 0;
}
When I compiled it and got the results like this:
2.000000, 1.000000
if you want to printf the address,you should use the type of argument that is %p, not %f.
What you do is basically lying (or at least cheating) to your library. If that's intented or by accident doesn't matter.
You tell the library that you want to print a double value.
Without knowing the real type, printf fetches content for a double from the variable parameter list.
But then you put an address into parameter list which is of wrong type and wrong size.
This does not only mean that the value for this parameter is printed incorrectly, but also that a wrong number of bytes is consumed from the input.
Therefore also the second parameter can be printed incorrectly because printf is reading from the wrong address.
You can use %p for printing the address,
Here aa and &aa[0] are both same, which holds the base address of the array.
try this:
printf("%p %p",&aa[0],aa); /*Which will give you the base address of array*/
You will get the o/p in Hex format.
i am trying to print value of an array in C-language.I am using 3 format specifier for only one value of array , my problem is that i don't understand that how other two values are coming in my output .
here is my code:
int arr[6] = {3,4,42,2,77,8};
printf("%d %d %d ",arr[2]);
output :
42 3 4
According to the C Standard
If there are insufficient arguments for the format, the behavior is
undefined.
In your call of printf
printf("%d %d %d ",arr[2]);
the arguments are exhausted after the first format specjfjer. So the function call has undefined behaviour and the output can contain any garbage.
You shall write
printf( "%d ", arr[2] );
or for example
printf( "%d %d %d ", arr[2], arr[3], arr[4] );
When printf() sees three format specifiers, it looks at specific locations, either in stack memory or in CPU registers, depending on the conventions of the compiler, for three arguments.
You provided one, but some data that you have no control over exists in the other two locations, and that's what gets printed.
The other two values are garbage and don't have any meaning. The function printf requires as many arguments as there are format specifiers, so in your case three. Since you only provided one argument (arr[2]), the other two specifier 'don't know' what to print - thus gargabe will come out. Make sure to provide the required number of arguments.
If you want to print the array number by number, you will have to use a for loop.
The signature of printf is.
int printf(char*, ...);
So, you can have a variable number of arguments, then.
printf("%d %d %d ",arr[2]);
Is a valid call of the function printf.
However, because you provided no values yourself, then you will get whatever... that in your special case it seems that it printed arr[0] and arr[1].
What is %*d ? I know that %d is used for integers, so I think %*d also must related to integer only? What is the purpose of it? What does it do?
int a=10,b=20;
printf("\n%d%d",a,b);
printf("\n%*d%*d",a,b);
Result is
10 20
1775 1775
The %*d in a printf allows you to use a variable to control the field width, along the lines of:
int wid = 4;
printf ("%*d\n", wid, 42);
which will give you:
..42
(with each of those . characters being a space). The * consumes one argument wid and the d consumes the 42.
The form you have, like:
printf ("%*d %*d\n", a, b);
is undefined behaviour as per the standard, since you should be providing four arguments after the format string, not two (and good compilers like gcc will tell you about this if you bump up the warning level). From C11 7.20.6 Formatted input/output functions:
If there are insufficient arguments for the format, the behavior is undefined.
It should be something like:
printf ("%*d %*d\n", 4, a, 4, b);
And the reason you're getting the weird output is due to that undefined behaviour. This excellent answer shows you the sort of things that can go wrong (and why) when you don't follow the rules, especially pertaining to this situation.
Now I wouldn't expect this to be a misalignment issue since you're using int for all data types but, as with all undefined behaviour, anything can happen.
When used with scanf() functions, it means that an integer is parsed, but the result is not stored anywhere.
When used with printf() functions, it means the width argument is specified by the next format argument.
The * is used as an indication that the width is passed as a parameter of printf
in "%*d", the first argument is defined as the total width of the output, the second argument is taken as normal integer.
for the below program
int x=6,p=10;
printf("%*d",x,p);
output: " 10"
the first argument ta passed for *, that defines the total width of the output... in this case, width is passed as 6. so the length of the entire output will be 5.
now to the number 10, two places are required (1 and 0, total 2). so remaining 5-2=3 empty string or '\0' or NULL character will be concatenated before the actual output
I have the following code, but I'm not sure what %0x%x means in the following code?
sprintf(buf, "pixel : %0x%x \n", gpbImageData[100]);
OutputDebugString(buf);
gpbImageData[100] is pointing to an image data in the memory.
Your example causes undefined behaviour. The format string will cause sprint to expect two int values:
%0x
%x
Both of these mean exactly the same thing - print a value as a hexadecimal number. However, the call you've shown passes only one argument.
Are you sure it doesn't say 0x%x? If it doesn't, it's probably supposed to... that would be more normal, and will print the passed-in value as a hexadecimal number prefixed with 0x.
Your code as shown should cause a warning. clang gives:
example.c:5:15: warning: more '%' conversions than data arguments [-Wformat]
printf("%0x%x\n", 125987);
~^
1 warning generated.
and gcc says:
example.c: In function ‘main’:
example.c:5: warning: too few arguments for format
example.c:5: warning: too few arguments for format
Both without providing any flags at all.
You certainly meant this format string "0x%x"
sprintf(buf, "pixel : 0x%x \n", gpbImageData[100]);
This adds the 0x prefix to the hexadecimal numbers when they are written in buf.
Note that you can achieve the same thing with the flag character #:
sprintf(buf, "pixel : %#x \n", gpbImageData[100]);
The correct format is "0x%x" as ouah and Carl Norum said. Whatever gpbImageData[100] content (pointer or number), %x will print its value as a hexadecimal number. 0x is just a text. Maybe "gpbImageData" is an array of pointers.