Print negative hex with 6 char in C - 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)));

Related

Converting a binary string to integer

When I try and convert my binary string to int I am receiving a couple of mistakes that I can not figure out. First I am reading from a file and the leading zeros are not showing up when I convert and the new line is showing zero.
This code I am using from this questions: Convert binary string to hexadecimal string C
char* binaryString[100];
// convert binary string to integer
int value = (int)strtol(binaryString, NULL, 2);
//output string as int
printf("%i \n",value)
My txt file and what I am expecting as an output:
00000000
000000010001001000111010
00000000000000000000000000000001
101010111100110100110001001001000101
What I get:
0
0
70202
1
-1127017915
This line:
char* binaryString[100];
Is declaring an array of 100 char pointers (or 100 strings). You probably meant this to declare a buffer of 100 characters to be interpreted as a single string:
char binaryString[100];
char *binaryString[100];
// You are creating an array of pointers in this scenario, use char binaryString[100] instead;
int value = (int)strtol(binaryString, NULL, 2);
// 101010111100110100110001001001000101 Is a 36 bit number, int (in most implementations) is 32 bit. use long long (64 bit in visual c++) as type and strtoll as function instead.
printf("%i \n",value)
Must be printf("%lld \n", value).
In summary:
#include "stdio.h"
#include "stdlib.h" // required for strtoll
int main(void)
{
char str[100] = "101010111100110100110001001001000101";
long long val = 0;
val = strtoll(str, NULL, 2);
//output string as int
printf("%lld \n", val);
return 0;
}
if im understanding this correctly you want to take a binary string so ones and zeros and convert it to a Hex string so 0-F, if so the problem is with the Write not the Convert, you specified '%i' as the written value format, what you need to do for hex is specify '%x'
Change this "printf("%i \n",value)" to "printf("%x\n",value)"

Binary to dec and hex in 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.

Leading zeros in Hexadecimal int variable C

I converting binary to HEXA but i need output with leading zeros. I use this number in this function -> creat(outfile, hexa_num); From 011101110111 I will get 777 but i need 0777. Here is my converting function. Any suggestions ?
char bin_final[]="011101110111";
char *a = bin_final;
int hexa_num = 0;
do {
int b = *a=='1'?1:0;
hexa_num = (hexa_num<<1)|b;
a++;
} while (*a);
Easy, just use strtoul() and regular snprintf(), no need to re-invent anything.
const unsigned long number = strtoul("011101110111", NULL, 2);
char buf[16];
snprintf(buf, sizeof buf, "%04lx", number);
puts(buf);
This prints
0777
Of course if you want to always just print it you can collapse the final three lines into just:
printf("%04lx\n", number);
You can use %04d: the 0 means leading Zeros in 4 digits.
e.g.:
printf("%04d", hexanum);
If you want it in an string use sprintf instead of printf. The number (int hexa_num) itself doesn't have leading zeros but you can format it, just as you have your binary number not as a number but as a character string.

c - char array isn't printing every value

I am currently creating an encryption/decryption application as practice, and to do that I have been trying to convert an integer into a char array using snprintf however, for example, if I have an integer with 4 digits, it only adds the first 3. Here is my code so far:
int encrypt(int num, bool type)
{
char buffer[sizeof(num)];
snprintf(buffer, sizeof(buffer), "%d", num);
printf(buffer);
return 0;
}
Any help would be awesome!
The buffer should have a size large enough to hold the digits of the conversion plus a final '\0' and a potential minus sign. sizeof(num) is the number of bytes for the int variable, most likely 4, not enough for the conversion of numbers larger than 999, but snprintf will not write more than the size of the buffer including the final '\0', hence only the first 3 digits.
You can either make an assumption on the size of int and define buffer as:
char buffer[12]; /* large enough for -2147483648 */
Or you can do it precisely and portably:
char buffer[sizeof(num) * CHAR_BIT / 3 + 3];

How to convert Hexadecimal to Decimal?

I have different hexadecimal data are coming and stored into an integer type register.
When I use fprint I can see the following:
0x3076
0x307c
.
.
.
However, I would like to show a Decimal version of above-mention Hex data as follows.
12406
12412
.
.
.
In theory, let's say for the first value you do the following to convert it to decimal.
(6* 16^0)+(7 * 16^1)+(0*16^2)+(3*16^3)=6 + 112+ 0 + 12288 = 12406
So IF I have the character-based version of "0x3076" and also, IF I am able to get each single characters 6 - 7 - 0 - 3, I can calculate the decimal amount!
So, I decided to divide "3076" by 1000. I was expected to get 3, but I got TWO characters instead! however, if I was able to get 3 for the remainder of "307c" I am not able to get "C". If it was decimal this might work not hex!
Also, I tried "strtol" command. As I use Cygwin to compile my code, I am not sure where the error is! What did I do wrong?
So, I just need to find a way to get EACH SINGLE character out of the HEX data!
Any idea please?
P.S.
Here is my code in order to help you to give me an idea.
int get_readings(int source, int phase, int max_tries)
{
uint8_t buf[MAX_IEC1107_MSG_BODY];
uint8_t inbuf[MAX_IEC1107_MSG_BODY];
int inlen;
uint8_t *s;
int32_t value;
int status;
double voltage;
double current;
double active_power;
double reactive_power;
double apparent_power;
double power_factor;
double frequency;
s = buf;
*s++ = HOST_CMD_GET_READINGS_PHASE_1 + phase;
*s++ = 0x00;
if (max_tries != 1)
meter_set_max_tries(&emeter[source].meter_msg, max_tries);
if (meter_exchange(&emeter[source].meter_msg, buf, 2, inbuf, &inlen)
&&
inbuf[1] != 0xFF)
{
emeter[source].no_response = FALSE;
s = inbuf;
/* Get current readings */
value = (s[3] << 8) | s[2];
fprint(stderr, "value:" %p\n, value); // this give me HEX code
.
.
.
When reading in a string representing a number in hexadecimal, use strtol() to convert it to a long. Then if you want to print the number in decimal, use printf() with a %d format specifier.
char num[]="0x3076";
long n = strtol(num, NULL, 16);
printf("n=%ld\n", n); // prints 12406
Once you read in the strings as longs using strtol and operate on the longs, the math should work itself out.
unsigned n;
sscanf("0x3076", "%x", &n);
printf("%u\n", n);
Only with the following line I could solve the issue!
fprintf(stderr, "Voltage: %.2f\n", value/100.00);
value was shown as HEX as I used to use %p! Then I changed to x! and as I need to have 124.06 not 12406, in other words 2 decimal points, I added .2f!
Thank you all!
1) for printing only:
#include <stdio.h>
#include <stdlib.h>
int main(){
int a=0;
scanf("%x",&a);
printf("%d\n",a);
system("pause");
return 0;
}
2) for calculation use:
#include<stdio.h>
#include<stdlib.h>
int CharToDec(char c){
if(c>='0' && c<='9') return c-'0';
if(c>='a' && c<='f') return c-'a'+10;
if(c>='A' && c<='F') return c-'A'+10;
return 0;
}
int main(int argc, char *argv[]){
char H[10];
char *P;
int p=1,d=0;
printf("Entrez Hexadecimale nombre:");
scanf("%s",H);
for(P=H;*P;P++);
for(P--;P>=H;P--){
d = d + (CharToDec(*P) * p);
p = p*16;
}
printf("%d\n",d);
system("pause");
return 0
}
You are confusing "integer" and "decimal" -- an "integer" is a number stored in a register or variable, while a "decimal" is a string of characters that represent a number in base 10.
So converting from hexadecimal to decimal is a two-step process. You first convert the hexadecimal to integer (which you appear to have done, with your "In theory" equation). You then convert the integer to decimal.
There are lots of ways to do either of these tasks, strtol and scanf will convert either hexadecimal or decimal to integer. printf can convert integer to either hexedecimal or decimal. Or you can write your own routines that manipulate characters to do either of these things.

Resources