How to display hexadecimal numbers in C? - c

I have a list of numbers as below:
0, 16, 32, 48 ...
I need to output those numbers in hexadecimal as:
0000,0010,0020,0030,0040 ...
I have tried solution such as:
printf("%.4x",a); // where a is an integer
but the result that I got is:
0000, 0001, 0002, 0003, 0004 ...
I think I'm close there. Can anybody help as I'm not
so good at printf in C.
Thanks.

Try:
printf("%04x",a);
0 - Left-pads the number with
zeroes (0) instead of spaces, where
padding is specified.
4 (width) - Minimum number of
characters to be printed. If the
value to be printed is shorter than
this number, the result is right justified
within this width by padding on the left
with the pad character. By default this is
a blank space, but the leading zero we used
specifies a zero as the pad char.
The value is not truncated even if the result is
larger.
x - Specifier for hexadecimal
integer.
More here

i use it like this:
printf("my number is 0x%02X\n",number);
// output: my number is 0x4A
Just change number "2" to any number of chars You want to print ;)

Your code has no problem. It does print the way you want. Alternatively, you can do this:
printf("%04x",a);

You can use the following snippet code:
#include<stdio.h>
int main(int argc, char *argv[]){
unsigned int i;
printf("decimal hexadecimal\n");
for (i = 0; i <= 256; i+=16)
printf("%04d 0x%04X\n", i, i);
return 0;
}
It prints both decimal and hexadecimal numbers in 4 places with zero padding.

Related

How to print a four character hexadecimal in C?

for (int x= 7; 0<=x; x--) {
size_t x_val = ((1<<4)-1) & io>>x*4;
printf("%lX", x_val);
Trying to print a hexadecimal number here after converting it from integer. While the conversion is successful, the output is FFFFFFCD instead of the desired output FFCD. How can I limit maximum 4 characters to be printed?
to print a four character hexadecimal
Limit value to the [0...0xFFFF] range.
Print 4 digits padded with zeros with the correct specifier.
Example
unsigned masked_value = io & 0xFFFF;
printf("%04X\n", masked_value);
Try this one,
You can use hh to tell printf that the argument is an unsigned char. Use 0 to get zero padding and 4 to set the width to 4. x or X for lower/uppercase hex characters.
uint8_t a = 0x0a;
printf("%02hhX", a); // Prints "0A"
printf("0x%02hhx", a);

How to print in HEX format the MSBs bits when they're equal to 0

I need to print variables using HEX format.
The problem is when my variables are little the MSBs equal 0 so they are not printed.
ex: uint16_t var = 10; // (0x000A)h
-> I need to print "000A" but no matter what I do it always prints just 'A'
How could I get it to work?
You can add a leading 0 to the width specifier in order to force printf to add leading zeros (at least, you can in C and C++ - not entirely sure about other languages that use the function).
For example, in C, the following:
#include <stdio.h>
#include <stdint.h>
int main()
{
uint16_t a = 10; // 0xA
printf("%04X\n", a);
// ^ width specifier: display as 4 digits
// ^ this signals to add leading zeros to pad to at least "n" digits
return 0;
}
will display:
000A

Printing the binary representation of an unsigned char backwards?

How exactly does this code work? I'm confused about the first for loop since binary starts at 0 and as long as it is not equal to the binary representation of the char it will increase, so then binary is 1 and so on?
unsigned char c;
int binary;
scanf("%c", &c);
getchar();
printf("The decimal representation is: %d\n", c);
for (binary = 0; (1<<binary)<=c; binary++){ // moving to the left
} // until binary code matches c
printf("The backwards binary representation is: ");
for (int i=0; i<binary; i++){ // since we know the size
printf("%d", ((c>>i)&1)); // 1s and 0s are shifted to right
}
printf("\n");
return 0;
This:
for (binary = 0; (1<<binary)<=c; binary++)
simply counts how many significant bits are in the integer "c".
For instance, if "c" is 0101100 in binary, the most significant bit is the 6th from the right, and "binary" would be set to 6.
If "c" is 01 in binary, the most significant bit is the first from the right, and "binary" would be set to 1.
The biggest problem with this code is its almost useless comments.
If there must be comments, replace this:
/* moving to the left until binary code matches c */
with this:
/* Count number of significant bits.*/
Comments should say why the code is there, not describe how it works.
Comments like this don't serve any purpose:
/* since we know the size 1s and 0s are shift to right */
The second biggest problem is the variable names. "binary" is misleading. Call it "number_of_significant_bits" instead and the code almost doesn't need any comments.

Integer range and Overflow

This is a simple program to convert positive decimal number into binary. I have to report and stop conversion of those numbers which could cause overflow or erroneous results. I found size of integer is 4 Bytes but it converts correctly upto 1023 only.
I am confuse where the number "1023" came from? Is there any method to calculate so i can predict what will be the correct range, if say, i am programming on another system.
#include<stdio.h>
int main(void)
{
int decimal,binary=0,y,m=1;
scanf("%d",&decimal);
if(decimal<=1023)
{
while(decimal>0)
{
y=decimal%2;
binary=binary+(m*y);
m=m*10;
decimal=decimal/2;
}
printf("\nBinary Equivalent is: %d",binary);
}
else
{printf("Sorry, The Number You've entered exceeds the maximum allowable range for conversion");}
getch();
return 0;
}
1023 is equal to 1024-1 (2^10 -1), so a number lesser than or equal to 1023 will have 10 digits in base 2. Since you are using an int to get the result, it stores up to 2^31-1 = 2147483647 (31 because one of the 32 bits is used to represent the sign (+ or -)). When you have a 1024 or higher number, it uses more than 10 digits - and, thus, is higher than 2147483647.
Hope that helps.
Actually, the range of an integer is between [-2^31, 2^31-1]. Because there are 4 bytes (i.e., 32 bits). However, if you want to scanf a non-negative integer. you have to initial a unsigned int rather int. The range will be [0, 2^32-1].
The problem is in the temporary variables binary and m you use. Because 1024 would take 11 divisions to become 0, m will become 10.000.000.000. However, the maximum value of an int is 2.147.483.647 (since one bit of the four bytes is used as a sign bit). m will thus overflow, which results in an incorrect result. 1023 or smaller values will take 10 devisions or less to become 0, so m is max 1.000.000.000, so m has no overflow.
You seem to want to take a 4 byte decimal number and convert it to a binary string of 0s and 1s. The method used in the code fails when the decimal number is > 1023. Here is a conversion that produces a string of 0s and 1s that can be printed using:
printf("\nBinary Equivalent is: ");
while( int i = 0; i < 32; i++ )
{
printf( "%c", (decimal & (1<<i) )? '1': '0');
}
printf("\n");
This eliminates much of the code clutter and produces the desired output.

ASCII and printf

I have a little (big, dumb?) question about int and chars in C. I rememeber from my studies that "chars are little integers and viceversa," and that's okay to me. If I need to use small numbers, the best way is to use a char type.
But in a code like this:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int i= atoi(argv[1]);
printf("%d -> %c\n",i,i);
return 0;
}
I can use as argument every number I want. So with 0-127 I obtain the expected results (the standard ASCII table) but even with bigger or negative numbers it seems to work...
Here is some example:
-181 -> K
-182 -> J
300 -> ,
301 -> -
Why? It seems to me that it's cycling around the ascii table, but I don't understand how.
When you pass an int corresponding to the "%c" conversion specifier, the int is converted to an unsigned char and then written.
The values you pass are being converted to different values when they are outside the range of an unsigned (0 to UCHAR_MAX). The system you are working on probably has UCHAR_MAX == 255.
When converting an int to an unsigned char:
If the value is larger than
UCHAR_MAX, (UCHAR_MAX+1) is
subtracted from the value as many
times as needed to bring it into the
range 0 to UCHAR_MAX.
Likewise, if the
value is less than zero, (UCHAR_MAX+1)
is added to the value as many times
as needed to bring it into the range
0 to UCHAR_MAX.
Therefore:
(unsigned char)-181 == (-181 + (255+1)) == 75 == 'K'
(unsigned char)-182 == (-182 + (255+1)) == 74 == 'J'
(unsigned char)300 == (300 - (255+1)) == 44 == ','
(unsigned char)301 == (301 - (255+1)) == 45 == '-'
The %c format parameter interprets the corresponding value as a character, not as an integer. However, when you lie to printf and pass an int in what you tell it is a char, its internal manipulation of the value (to get a char back, as a char is normally passed as an int anyway, with varargs) happens to yield the values you see.
My guess is that %c takes the first byte of the value provided and formats that as a character. On a little-endian system such as a PC running Windows, that byte would represent the least-significant byte of any value passed in, so consecutive numbers would always be shown as different characters.
You told it the number is a char, so it's going to try every way it can to treat it as one, despite being far too big.
Looking at what you got, since J and K are in that order, I'd say it's using the integer % 128 to make sure it fits in the legal range.
Edit: Please disregard this "answer".
Because you are on a little-endian machine :)
Serously, this is an undefined behavior. Try changing the code to printf("%d -> %c, %c\n",i,i,'4'); and see what happens then...
When we use the %c in printf statement, it can access only the first byte of the integer.
Hence anything greater than 256 is treated as n % 256.
For example
i/p = 321 yields op=A
What atoi does is converting the string to numerical values, so that "1234" gets 1234 and not just a sequence of the ordinal numbers of the string.
Example:
char *x = "1234"; // x[0] = 49, x[1] = 50, x[2] = 51, x[3] = 52 (see the ASCII table)
int y = atoi(x); // y = 1234
int z = (int)x[0]; // z = 49 which is not what one would want

Resources