As we all know, each printable character has its ascii value. I'm trying to 8 characters' ascii value to 64 bits integer, but it only copies 32 bits.
char * ch = "AAAABBBB";
unsigned long int i;
//copy charater's ascii to 64 bits int
memcpy(&i, ch, 8);
printf("integer hold: 0x%x\n", i);
Is there something wrong with this code?
Output I expect was:
integer hold: 0x4141414142424242
but output was:
integer hold: 0x41414141
If unsigned long is indeed a 64-bit type (you can output sizeof(unsigned long) to check this), you still need to use %lx format string to print it.
If unsigned long is 32 bits, you'll probably have to resort to unsigned long long and use the %llx format string.
From C11 7.20.6.1 The fprintf function:
o,u,x,X The unsigned int argument is converted to unsigned octal (o), unsigned decimal (u), or unsigned hexadecimal notation (x or X) in the style dddd; the letters abcdef are used for x conversion and the letters ABCDEF for X conversion. The precision specifies the minimum number of digits to appear; if the value being converted can be represented in fewer digits, it is expanded with leading zeros. The default precision is 1. The result of converting a zero value with a precision of zero is no characters.
l (ell): Specifies that a following d, i, o, u, x, or X conversion specifier applies to a long int or unsigned long int argument.
ll (ell-ell): Specifies that a following d, i, o, u, x, or X conversion specifier applies to a long long int or unsigned long long int argument.
long versus long long.
In VC++ the long datatype is still only 32 bits.
And of course, the printf format %x is used for int which is 32 bits on most platforms. You want %llx (or possibly %lx if your long already is 64 bits).
%x is used to print unsigned int value & its 32 bit that's why you are getting such result.
%d %i Decimal signed integer.
%o Octal integer.
%x %X Hex integer.
%u Unsigned integer.
%c Character.
%s String.
%f double
%e %E double.
%g %G double.
%p pointer.
& if you want to print the remaining data try ...
int *p;
p=(char *)(&i)+4;
printf("integer hold: 0x%x\n", i);
printf("integer hold: 0x%x\n",*p);
Related
**Allocation and Storage part of C programming **
I have come with some doubt while trying to print negative numbers through different number system.
while printing negative numbers, I am getting different output values.But I am not understanding clearly. If anybody help me will be appreciative.
#include<stdio.h>
int main( )
{
char a = -5;
unsigned char b = -5;
int c = -5;
unsigned int d = -5;
//try to print as using "%d" format specifier to display decimal value
printf("%d %d",a,b);
printf("%d %d",c,d);
//try to print as using "%o" format specifier to display octal value
printf("%o %o",a,b);
printf("%o %o",c,d);
//try to print as using "%x" format specifier to display hexa-decimal value
printf("%x %x",a,b);
printf("%x %x",c,d);
return 0;
}
Output:-
displaying decimal value
a = -5 b = 251
c = -5 d = -5
displaying octal value
a = 37777777773 b = 373
c = 37777777773 d = 37777777773
displaying Hexa-decimal value
a = fffffffb b = fb
c = fffffffb d = fffffffb
Now, come to the point. I don't know why unsigned char would take only 8 bits(1 Byte) and other gets allocated to 32 bits (4 Bytes).
When a char value is passed to printf, it is promoted to int. printf is printing this int value.
When the char value is −5 and it is promoted to int, the int value is −5. For a 32-bit two’s complement int, −5 is represented with the bits fffffffb16. So, when you ask printf to format that with %x, you can “fffffffb”. (Technically, %x is for an unsigned int, and passing an int does not match, but most C implementations will accept it.) The eight-bit char was promoted to a 32-bit int, and that is why you see 32-bit results.
You can tell printf that the value it receives originated as a character value by using %hho or %hhx instead of %o or %x, and it may adjust accordingly. (Again, the o and x specifiers are for unsigned int values, and passing an int does not match, but it may work.) A pedantically correct solution is to use (unsigned int) (unsigned char) x when passing a signed char x for a %o or %x conversion.
I am not understanding what is major difference between %p,%u,%x,%d, except that %x shows hexadecimal,%u is used for unsigned integer and that %d is for any integer. I am very much confused after I took a integer variable and printed its address and its value (positive integer) separately, then irrespective of whatever format specifier I use, it was correctly printing the output (except of the difference in hexadecimal and decimal number system). So what is a major difference?
And if there is not much difference then which format specifiers are preferable for printing what type of variables?
Another doubt is that: Whether pointer of all multiplicity (I mean int *p; int **p; int ***p; etc.) occupy the same size (which is the size needed to store a valid address in the machine)? If not, then what is the size of these pointers?
Thanks for your help.
The %u, %x, %d, and %p format specifiers are used as follows:
%u: expects an unsigned int as a parameter and prints it in decimal format.
%x: expects an unsigned int as a parameter and prints it in hexadecimal format.
%d: expects an int as a parameter and prints it in decimal format.
%p: expects a void * as a parameter and prints it in an implementation defined way (typically as a hexadecimal number)
Additionally, %u, %x, %d can be prefixed with a length modifier:
l: denotes a long int or unsigned long int
ll: denotes a long long int or unsigned long long int
h: denotes a short int or unsigned short int
hh: denotes a signed char or unsigned char
Regarding pointer sizes, int *, int **, int ***, etc. are not required to be the same size, although on most implementations they will be.
With format specifiers, you tell the computer how to interpret the given variable/data.
A quick demo:
#include <stdio.h>
int main(void)
{
int x = -5;
printf("x value as int: [%d]\n", x);
printf("x value as unsigned int: [%u]\n", x);
printf("x value as hexadecimal: [%x]\n", x);
printf("x value as pointer: [%p]\n", x);
return 0;
}
Output:
x value as int: [-5]
x value as unsigned int: [4294967291]
x value as hexadecimal: [fffffffb]
x value as pointer: [0xfffffffb]
It's the same value given every time, i.e. x = -5.
We see the exact representation when given the right format specifier (the first case).
In second case we see a very big number. The answer to "Why" is a bit long to explain here, but you should look up how negative integers are represented in 2's complement system.
In the third case we see the hexadecimal representation of the number 4294967291. Hexadecimal numbers are usually shown with 0x at the beginning but %x doesn't do that.
The last one just shows how would the variable x seem if it were an address in the memory, again in hexadecimal format of course.
am trying to pass along a "long long" number, the problem is when I try to divise this number by 10 , the answer is incorrect ..
#include <stdio.h>
int main(void)
{
int n = 0 ;
long long s = 4111111111111111;
n = s % 10 ;
printf("n after modulos %i\n",n );
s = s / 10 ;
printf("this is s after division %llo \n",s );
return 0;
}
Output :
n after modulos 1
this is s after division 13536350357330707
printf("this is s after division %llo \n",s );
^ (this prints (correct)value in octal representation)
Use specifier %lld (to get value in decimal ) .
man 3 printf
o, u, x, X
The unsigned int argument is converted to unsigned octal (o), unsigned decimal (u), or unsigned hexadecimal (x and X) notation. The letters abcdef are used for x conversions; the letters ABCDEF are
used for X conversions. The precision, if any, gives the minimum number of digits that must appear; if the converted value requires fewer digits, it is padded on the left with zeros. The default
precision is 1. When 0 is printed with an explicit precision 0, the output is empty.
and some more on manual
man 3p printf
ll (ell-ell)
Specifies that a following d, i, o, u, x, or X conversion specifier applies to a long long or unsigned long long argument; or that a following n conversion specifier applies to a pointer to a long
long argument.
To print a long long, you should use %lld not %llo
The %llo format is used for representing a long long value in octal.
I have a function that gets an unsigned long variable as parameter and I want to print it in Hex.
What is the correct way to do it?
Currently, I use printf with "%lx"
void printAddress(unsigned long address) {
printf("%lx\n", address);
}
Should I look for a printf pattern for unsigned long hex? (and not just "long hex" as mentioned above)
Or does printf convert numbers to hex only using the bits? - so I should not care about the sign anyway?
Edit/Clarification
This question was rooted in a confusion: hex is just another way to express bits, which means that signed/unsigned number is just an interpretation. The fact that the type is unsigned long therefore doesn't change the hex digits. Unsigned just tells you how to interpret those same bits in your computer program.
You're doing it right.
From the manual page:
o, u, x, X
The unsigned int argument is converted to unsigned octal (o), unsigned decimal (u), or unsigned hexadecimal (x and X) notation.
So the value for x should always be unsigned. To make it long in size, use:
l
(ell) A following integer conversion corresponds to a long int or unsigned long int argument [...]
So %lx is unsigned long. An address (pointer value), however, should be printed with %p and cast to void *.
I think the following format specifier should work
give it a try
printf("%#lx\n",address);
#include <stdio.h>
#include <string.h>
int main(void) {
char buf[256] = {};
unsigned long i=13835058055298940928;
snprintf(buf, 1024, "%lx", i); /* Line 7 */
printf("%s\n",buf);
return 0;
}
In line 7, if I use %lux, and then snprintf doesn't do any conversion. It just prints 0x13835058055298940928x, whereas if I use just %lx, it prints an expected hexadecimal conversion.
How do I represent unsigned long in hexadecimal?
A format of "%lux" is treated as "%lu" (unsigned long, decimal) followed by a letter x.
The "%x" format requires an argument of unsigned type; there's no (direct) mechanism to print signed integers in hexadecimal format.
The format for printing an unsigned long value in hexadecimal is "%lx". (x is hexadecimal, d is signed decimal, u is unsigned decimal; any of them may be qualified with l for long.)
Note that the value 13835058055298940928 requires at least a 64-bit unsigned type to store it without overflow. The type unsigned long is at least 32 bits; it's 64 bits on some systems, but by no means all. If you want your code to be portable, you should use type unsigned long long rather than unsigned long. The format for printing an unsigned long long value in hexadecimal is "%llx".
For clarity, I usually precede hexadecimal output with 0x, so it's obvious to the reader that it's a hexadecimal number:
printf("0x%llx\n", some_unsigned_long_long_value);
(You can achieve the same result with %#llx, but I find it easier to write out 0x than to remember the meaning of the # flag.)