Binary to dec and hex in C - c

I would like to create function that will return numbers in hexidecimal. But I am getting some wrong numbers after changing to decimal numbers. In output, the first number is binary, second one also binary but in int format, and third one should be decimal. But I am getting wrong numbers in decimal (see the second line, where it shoud be 156, not 220). Could anyone explain me what am i doing wrong and how can I get right numbers? Thank you. Here is my output:
char *encrypted = calloc((size_t)TEXT_LEN*3, sizeof(char));
int number[TEXT_LEN];
index=0;
for(int i=0;i<TEXT_LEN;i++){
number[i]=atoi(binary[i]);
printf("%s ",binary[i]);
printf("%d ",number[i]);
printf("%d\n",(unsigned char)number[i]);
sprintf(encrypted+index,"%x ",(unsigned char)number[i]);
index+=3;
}
printf("%s\n",encrypted);
free(encrypted);
EDIT: I found solution in comments, and I fixed it by using function strtol in line:
number[i] = strtol ( binary[i], NULL, 2);

In case of number values smaller than 16 the written string length is two and at the end the char '\0' is inserted. Use either a fixed size
sprintf(encrypted+index,"%02x ", number[i]);
index += 3;
or use the return value from the sprintf function which is the written string length to increment the index
index += sprintf(encrypted+index,"%x ", number[i]);
I would prefer a combination of both
index += sprintf(encrypted+index,"%02x ", number[i]);
Based on the eight character string in binary the method of user3121023 above will give you the right decimal number
number[i] = strtol(binary[i], NULL, 2);
printf("%s ", binary[i]); // 1st col
printf("%d\n", number[i]); // 2nd col

In the second line of output, I wrote a C plus plus program to explain your doubt:
int value = 10011100;
cout<<bitset<sizeof(int)*8>(value)<<value<<endl; // 0000000010011000110000011101110010011100
unsigned char va = (unsigned char)value;
cout<<bitset<sizeof(unsigned char)*8>(va)<<endl; // 11011100
the decimal number 10011100 convert to binary number 10011000110000011101110010011100, then it is put in unsigned char, we get 11011100, it is 220.

Related

Print negative hex with 6 char in C

I try to print a negative number in hex and I want it to be in 6 char.
For example, -132 in hex is ffffff7c and the wanted output should be ffff7c.
For positive number this line work:
fprintf(fd,"%07d \t%06x \n",i+100,instruction_data[i]);
for negative numbers, I get two more f.
Based on the solution provided by #pmg in comments:
#include <stdio.h>
void print_hex (int val, size_t digits)
{
char tmp[100];
size_t length = sprintf(tmp, "%X", (unsigned int)val);
if(digits > length)
{
digits = length;
}
printf("%.*s\n", digits, tmp+length-digits);
}
int main (void)
{
print_hex(-132,6); // FFFF7C
print_hex(-132,3); // F7C
print_hex(-132,666); // FFFFFF7C
print_hex(132,2); // 84
}
Explanation:
The sprintf call converts the passed number to ASCII hex and stores it in a temporary buffer.
The cast to unsigned int is necessary for the %X specifier.
sprintf returns the number of characters written.
if(digits > length) { digits = length; } is some simple error handling to ensure that the function doesn't attempt to print more digits than present.
The %.*s trick in printf allows the first parameter to specify how many characters to write, variably.
tmp+length-digits is pointer arithmetic ensuring to print digits number of characters from the end of the string, rather than from the beginning, which we would have gotten if we just wrote tmp.
To only print 6 hex digits for negative numbers on 32-bit architectures, you can simply mark the value with 0xffffff:
fprintf(fd, "%07d \t%.6x \n", i + 100, instruction_data[i] & 0xffffffU);
To specify the number of digits as an int variable:
int digits = 6;
...
fprintf(fd, "%07d \t%.*x \n", i + 100, digits,
instruction_data[i] & ~(~0U << (digits * 2) << (digits * 2)));

How to save hexadecimal ASCII values to array (buffer) in C?

I have an int value in the input and I want to save it to a buffer/array as a hexadecimal representation of ASCII.
I know how to print it in hex form but how can I save it like this to the buffer?
Here's the code I wrote:
int a = 98765;
char buffer[20];
m = sprintf(buffer, "%d", a);
printf("ASCII value in hex: ");
for(int i=0; buffer[i]!='\0'; i++)
{
printf("%02X", buffer[i]);
}
for eg if a=123 I want to get 313233
The first sprintf gave you an array of char, where each one is in the range 0x30 to 0x39. You want those to be expanded to the two characters '3' and '0', '3' and '1', etc.
You're expanding each char in the source to two chars in the output, which means you can't use the same destination buffer as source buffer -- you'd overwrite values in the source buffer before you processed them. You probably want to do the first sprintf into a separate array of char if you need the result in buffer. In your loop, change the printf to a sprintf to an index in buffer, incrementing your index by two each loop. (By two because that way you'll be overwriting the first iteration's string terminator with the second iteration's sprintf output, which will include a new string terminator. The sprintf in the last iteration of the loop will terminate the string for you.)
You didn't mention the longest input you're supposed to handle, or why you chose the array lengths you did. There's a danger of buffer overruns here if you accept inputs that are too long for your buffers (and don't forget to account for space for the null termination after the last character.)
You have already used sprintf to represent decimal values as a string; you can do the same for hexadecimal formatting.
Use the return value of sprintf() (which is the number of characters 'printed') to advance an index into the buffer as the destination for the next hex-digit pair, then iterate each character in the decimal buffer.
Note that, you can use the return value (m) from the first sprintf() for the iteration rather then testing for nul.
char hexbuffer[64];
int index = 0 ;
for(int i = 0; i < m; i++)
{
index += sprintf( &hexbuffer[index], "%02X", buffer[i] ) ;
}
Of course if the input includes only decimal digits (i.e. the user does not enter a negative value causing a - at buffer[0], you could simply insert a 3 ahead of each decimal digit, thus:
char hexbuffer[64];
for(int i = 0; i < m; i++)
{
bexbuffer[i * 2] = '3' ;
hexbuffer[i * 2 + 1] = buffer[i]
}
If only decimal digits were intended, you should change the type of a to unsigned and use the %u format specifier for the decimal input.

Some more explanation about an array example I found online

I'm just starting out to learn program in C and am trying to get my head around arrays. I found this example online but don't understand how it works. Here is the code:
#include <stdio.h>
int main () {
int n[ 10 ]; /* n is an array of 10 integers */
int i,j;
/* initialize elements of array n to 0 */
for ( i = 0; i < 10; i++ ) {
n[ i ] = i + 100; /* set element at location i to i + 100 */
}
/* output each array element's value */
for (j = 0; j < 10; j++ ) {
printf("Element[%d] = %d\n", j, n[j] );
}
return 0;
}
What I don't understand here is how int j links to int i. In the output, at the printf line, I don't understand why it is not:
printf("Element[%d] = %d\n", i, n[i]);
Why do we need another int j?
And another thing I don't understand is the %d's in that line. Why %d and not %i? d hasn't been declared anywhere right?
Any deeper explanation than on the website where I found this example would be appreciated. Thank you.
Why do we need another int j?
You don't. I'm assuming the author was just demonstrating that you can use any variable to index into an array, as long as the variable has the right type (pretty much any integral type) and holds a value in the correct range.
Array indices can be any integral expression, whether it's an integral constant (a[5]), a variable (a[i], a[j]), or a more complex expression (a[i+j], a[foo(i)], a[1+j*k/2], etc.). All that matters is that the expression has an integral type, and that its result is in the correct range (0 to N-1, where N is total number of elements in the array).
And another thing I don't understand is the %d's in that line. Why %d and not %i? d hasn't been declared anywhere right?
%d is a conversion specifier - it has nothing to do with any variable, and does not need to be declared separately. Conversion specifiers in the format string tell printf the number and types of additional arguments, and how to format those values for display.
In the line
printf("Element[%d] = %d\n", i, n[i]);
the %d specifiers in the format string tell printf that i and n[i] both have type int, and that they are to be formatted as decimal integers (as opposed to hex or octal, for example).
Here's an incomplete list of conversion specifiers:
Specifier Argument Type Output format
--------- ------------- -------------
%d,%i int decimal integer
%u unsigned int decimal integer (non-negative)
%f double decimal floating point
%x,%X unsigned int hexadecimal integer (non-negative)
%o unsigned int octal (non-negative)
%c char single character
%s char * text
Check your handy C reference manual for a complete list. If you don't have a handy C reference manual, I recommend Harbison & Steele's C: A Reference Manual.
Agreeing with # Eugene Sh, that in this case, j is indeed an extra variable.
The coding would be as shown below, and would return the same output.
for (i = 0; i < 10; i++) {
printf("Element[%d] = %d\n", i, n[i]);
}
And another thing I don't understand is the %d's in that line.
The printf() family of functions uses % character as a placeholder. This is a format specifier and does not require initialization. When a % is encountered, printf reads the characters following the % to determine what to do:
%s - Take the next argument and print it as a string
%d - Take the next argument and print it as an int
Sooner or later you might also encounter %s, which indicates that you're expecting a String to be your first print parameter.
Hope this helps.
What I don't understand here is how int j links to int i
They don't "link" and there is actually no connection between the two. The author simply used another integer (j) to avoid confusion.
As for your suggestion:
In the output, at the printf line, I don't understand why it is not:
printf("Element[%d] = %d\n", i, n[i]);
It is perfectly fine to do so if you make sure to use i as the loop variable for the second loop as well like so:
for (i = 0; i < 10; i++ ) {
printf("Element[%d] = %d\n", i, n[i] );
}
And another thing I don't understand is the %d's in that line. Why %d and not %i? d hasn't been declared anywhere right?
%d is a type modifier that tells the printf function to replace it with a decimal number when printing. It has nothing to do with some sort of variable named d. Your confusion might originated from the fact that there is also a %i modifier for printf but it is less commonly used. Refer to this wiki for more details.

How can I print the decimal representation of a character in c?

I am trying to figure out how to print the ascii value of a character in binary. Here is what I have done so far, but it does not work at all and I dont know why. Can someone of you C wizards help me??
#include <stdio.h>
int main(int argc, char** argv)
{
char myChar;
printf("Enter a character:\n");
scanf("%c", &myChar);
printf("Your character is %c\n", myChar);
printf("ASCII in BIN: %c\n", toBinary(myChar));
return 0;
}
char* toBinary(int decimalNumber)
{
char binaryValue[7] = "";
for (int i = sizeof(binaryValue); i >= 0; ++i)
{
int remainder = decimalNumber % 2;
decimalNumber = decimalNumber / 2;
binaryValue[i] = remainder;
}
return &binaryValue;
}
The %c format string will always interpret the corresponding printf argument as a character. In this case, its probably not what you want.
printf("ASCII in BIN: %d\n", myChar);
will print out the ascii code point of myChar just by telling printf to treat it as a number.
If you'd like to print out the string being returned by your toBinary function, you can do that with
printf("ASCII in BIN: %s\n", toBinary(myChar));
There's a good reference of the various % codes and what they mean here.
However, it's also worth noting that your toBinary function probably doesn't do what you want. This loop condition:
for (int i = sizeof(binaryValue); i >= 0; ++i)
will start at sizeof(int) and count up until it runs out of integers, then stop only because INT_MAX + 1 == INT_MIN. Because you're using i as an array index, this will almost certainly crash your program.
You also need to make sure to terminate the string you're generating with a '\0', as that is how subsequent calls to printf will recognize the string has ended.
And, as noted in other answers, your toBinary implementation is also returning a pointer to a memory address that will get automatically deleted as soon as toBinary returns.
You are returning address of local array.
This is both incorrect return type (char ** vs char *) and a bad thing to do at all.
printf("ASCII in BIN: %c\n", toBinary(myChar));
%c is to print a character.
And, there is no BOOL type in C, so you can change it in to a string, and pass the pointer to an array to printf("%s", pointer)

Help needed for basic C input and output

I need to get two inputs- hexadecimal address and number of bits- and then I need to print out the index and the offset of the address.
Thus, If the inputs are 20 and 0x0FF10100, the output should be 0x0FF1 for index and 0100 for the offset.
int bits, index, offset, count;
short addr[10], addr2;
printf("# of bits: ");
scanf("%d", &bits);
index = (bits / 4) + 2;
offset = 10 - index;
printf("Integer (in hex): ");
scanf("%hi", addr);
Then I need to output the index which is (20/4)+2 = 7 that means first 7 characters of the address. And the rest as offset.
I could not use printf i tried many times. But i could not fix I hope someone could help
Thanks everyone.
For output I tried to use
while (count < index)
{
printf("", addr[count], addr[count]);
count++;
}
It did not print out anything...
then I tried many variations of that and I got error. I dont know what to use to output..
Thanks
Maybe I'm missing something, but your printf call is using an empty string instead of a format string. You can see the various format specifiers here.
Always check the return value of scanf if you intend on using the input; it will return the number of items that it has successfully scanned. If you ignore the return value, you risk attempting to read indeterminate values, which means your program has undefined behaviour.
Also, in your second call to scanf, you aren't asking for a hexadecimal integer, you are asking for a short integer (h means short, and i means integer). If you want to scan a hexadecimal short integer, you need to use hx, but this also means you need to provide the address of an unsigned short, rather than a plain short.
int bits, index, offset, count;
unsigned short addr[10], addr2;
printf("# of bits: ");
if (scanf("%d", &bits) != 1)
{
// could not scan
// handle scan error here. Exit, or try again, etc.
}
index = (bits / 4) + 2;
offset = 10 - index;
printf("Integer (in hex): ");
if (scanf("%hx", addr) != 1)
{
// could not scan
// do whatever makes sense on scan failure.
}
If you are reading into consecutive elements of your addr array, you might want the following instead:
printf("Integer (in hex): ");
if (scanf("%hx", &addr[count]) != 1)
{
// could not scan
// do whatever makes sense on scan failure.
}
Finally regarding your use of printf: the first argument to printf tells it how to print the provided data. You have given it an empty string which means printf is not told to print anything. Perhaps you are looking for something like this:
printf("%d: %hx", count, addr[count]);

Resources