C convert hex to decimal format - c

Compiling on linux using gcc.
I would like to convert this to hex. 10 which would be a.
I have managed to do this will the code below.
unsigned int index = 10;
char index_buff[5] = {0};
sprintf(index_buff, "0x%x", index);
data_t.un32Index = port_buff;
However, the problem is that I need to assign it to a structure
and the element I need to assign to is an unsigned int type.
This works however:
data_t.un32index = 0xa;
However, my sample code doesn't work as it thinks I am trying to convert
from an string to a unsigned int.
I have tried this, but this also failed
data_t.un32index = (unsigned int) *index_buff;
Many thanks for any advice,

Huh? The decimal/hex doesn't matter if you have the value in a variable. Just do
data_t.un32index = index;
Decimal and hex are just notation when printing numbers so humans can read them.
For a C (or C++, or Java, or any of a number of languages where these types are "primitives" with semantics closely matching those of machine registers) integer variable, the value it holds can never be said to "be in hex".
The value is held in binary (in all typical modern electronic computers, which are digital and binary in nature) in the memory or register backing the variable, and you can then generate various string representations, which is when you need to pick a base to use.

I agree with the previous answers, but I thought I'd share code that actually converts a hex string to an unsigned integer just to show how it's done:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *hex_value_string = "deadbeef";
unsigned int out;
sscanf(hex_value_string, "%x", &out);
printf("%o %o\n", out, 0xdeadbeef);
printf("%x %x\n", out, 0xdeadbeef);
return 0;
}
Gives this when executed:
emil#lanfear /home/emil/dev $ ./hex
33653337357 33653337357
deadbeef deadbeef

However, my sample code doesn't work as it thinks I am trying to convert from an string to a unsigned int.
This is because when you write the following:
data_t.un32index = index_buff;
you do have a type mismatch. You are trying to assign a character array index_buff to an unsigned int i.e. data_t.un32index.
You should be able to assign the index as suggested directly to data_t.un32index.

Related

wrong conversion of two bytes array to short in c

I'm trying to convert 2 bytes array to an unsigned short.
this is the code for the conversion :
short bytesToShort(char* bytesArr)
{
short result =(short)((bytesArr[1] << 8)|bytesArr[0]);
return result;
}
I have an InputFile which stores bytes, and I read its bytes via loop (2 bytes each time) and store it in char N[] arr in this manner :
char N[3];
N[2]='\0';
while(fread(N,1,2,inputFile)==2)
when the (hex) value of N[0]=0 the computation is correct otherwise its wrong, for example :
0x62 (N[0]=0x0,N[1]=0x62) will return 98 (in short value), but 0x166 in hex (N[0]=0x6,N[1]=0x16) will return 5638 (in short value).
In the first place, it's generally best to use type unsigned char for the bytes of raw binary data, because that correctly expresses the semantics of what you're working with. Type char, although it can be, and too frequently is, used as a synonym for "byte", is better reserved for data that are actually character in nature.
In the event that you are furthermore performing arithmetic on byte values, you almost surely want unsigned char instead of char, because the signedness of char is implementation-defined. It does vary among implementations, and on many common implementations char is signed.
With that said, your main problem appears simple. You said
166 in hex (N[0]=6,N[1]=16) will return 5638 (in short value).
but 0x166 packed into a two-byte little-endian array would be (N[0]=0x66,N[1]=0x1). What you wrote would correspond to 0x1606, which indeed is the same as decimal 5638.
The problem is sign extension due to using char. You should use unsigned char instead:
#include <stdio.h>
short bytesToShort(unsigned char* bytesArr)
{
short result = (short)((bytesArr[1] << 8) | bytesArr[0]);
return result;
}
int main()
{
printf("%04x\n", bytesToShort("\x00\x11")); // expect 0x1100
printf("%04x\n", bytesToShort("\x55\x11")); // expect 0x1155
printf("%04x\n", bytesToShort("\xcc\xdd")); // expect 0xddcc
return 0;
}
Note: the problem in the code is not the one presented by the OP. The problem is returning the wrong result upon the input "\xcc\xdd". It will produce 0xffcc where it should be 0xddcc

C output of hexadecimal division different from all other sources

I want to divide two hex numbers:
for example: 88555680/10000
Now, from online hex calculators, I find:
8855 as result here
8855.568 as result here
And in python I find:
>>> hex(int("0x88555680",16)//int("0x10000", 16))
'0x8855'
Here is my C code:
# include <stdio.h>
int main() {
int a = 0x88555680;
int b = 0x10000;
int c = a/b;
printf("a%x, b%x, c%x\n", a, b, c);
}
With output:
a88555680, b10000, cffff8856
In C, I find 8856, while with Python, and online calculators, I find 8855
Question: Why is the C output not 8855? Why is it 8856? Should it not be 8855.something and then truncated towards 0, thus 8855?
I'm very new to C, it might be an obvious error.
On common systems int is a 32-bit type whose max value is 0x7FFFFFFF. Your value of 0x88555680 is out of range for int. The compiler should warn you about this; if you don't see a warning then I recommend adjusting compiler settings.
Also your code causes undefined behaviour by using %x to print an int. The %x specifier may only be used for unsigned int.
To fix your code in this case use unsigned int instead of int for all 3 variables. If you want to deal with larger numbers you can use unsigned long long, or uint64_t. (In those cases you will need to update the printf format specifiers too).

How to convert ascii number to uint64 in C?

I'm using Mini Ini to read data from .ini files on an embedded system. It supports reading in long integers or strings. Some of the numbers I have are too large to fit in a long, so I am reading them in as a string. However, I need to then convert them to a uint64_t.
I attempted to convert it to a float using atof and casting that to a uint64_t, which crashed and burned, presumably because casting changes how the program views the bits without changing the bits themselves.
char string_in[100];
//ret = ini_gets(section,key,"default_value",string_in,100,inifile);
//To simplify, use
string_in = "5100200300";
uint64_t value = (uint64_t)atof(string_in);
I would appreciate help on how to convert a string to a uint64.
EDIT: Conclusion
The atoll function converts ascii to long long, which serves the purpose I needed. However, for the sake of completeness, I implemented the function provided in the accepted answer and that provided the exact answer to my question.
You could write your own conversion function:
uint64_t convert(const char *text)
{
uint64_t number=0;
for(; *text; text++)
{
char digit=*text-'0';
number=(number*10)+digit;
}
return number;
}
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
static_assert(sizeof(uint64_t) == sizeof(long long),
"Your system is mighty weird");
uint64_t u64 = strtoull(string, NULL, 10);

Convert Int to Hexdecimal without using 'printf' (C Programming)

Is it possible to Convert Int to Hexdecimal without using 'printf'?
Best if the all the value are placed in the variable itself and some sample code with explanation.
The decimal and hexadecimal systems are just ways of expressing the value of the int. In a way "it is already a hexadecimal".
I think you can use itoa in stdlib.h :
char * itoa ( int value, char * str, int base ); or sprintf(str,"%x",value);
The documentation : itoa documentation
Of course it is possible. Just think about how printf itself was originally implemented...
I won't give you a full solution, only hints, based on which you can experiment with the implementation in code:
An 8-bit number can be expressed as 2 hex digits, which contain the higher and lower 4 bits, respectively. To get these bits, you can use the bit-shift (>>) and mask (&) operators.
Once you have a 4-bit value, you can easily map it to the correct hex digit using a sequence of ifs, or (as a more elegant solution) by indexing into a character array.
Hexdecival vs Decimal vs Binary..etc.. are only different bases that represent the same number. printf doesn't convert your number, it generates an hexdecimal string representation of your number. If you want to implement your own study how to make a conversion between decimal and hexdecimal bases.
Yes, it is definitely possible to convert an integer to a hexadecimal string without using the "printf" family of formatting functions.
You can write such a function by converting the number from base-10 (as we think about it) to base-16 (hexadecimal) and printing the digits in that representation (0-9A-F). This will require you to think a lot about the bases we use to represent numbers.
If you are referring to displaying an int as a hexadecimal number in C, than you will have to write a function that does the same thing as printf.
If you are referring to casting or internal representation, it can't be done because hexadecimal is not a data type.
An int is stored in your computer as a binary number. In fact, since hex can be interpreted as a shorthand for writing binary, you might even say that when you print out a decimal number using printf, it has to be converted from hex to decimal.
it's an example for convert a char array to hex string format
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
unsigned char d=255;
char hex_array[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char *array_to_hex_string(uint8_t data[],int size);
char test_data[3] = {'0',188,255};
int main()
{
printf("%s",array_to_hex_string(test_data,3));
return 0;
}
char *array_to_hex_string(uint8_t data[],int size){
int i,j;
char *hex_string = (char *)malloc((2*size) * sizeof(data[0]));
for(i=0;i<size;i++){
hex_string[j] = hex_array[(data[i]>>4)];
hex_string[j+1] = hex_array[(data[i] & 15)];
j +=2;
}
return (char *)hex_string;
}
cout << hex << intvar << endl;
But if you want an answer that gives you an A for your homework, you're not going to get lucky :)

Char C question about encoding signed/unsigned

I read that C not define if a char is signed or unsigned, and in GCC page this says that it can be signed on x86 and unsigned in PowerPPC and ARM.
Okey, I'm writing a program with GLIB that define char as gchar (not more than it, only a way for standardization).
My question is, what about UTF-8? It use more than an block of memory?
Say that I have a variable
unsigned char *string = "My string with UTF8 enconding ~> çã";
See, if I declare my variable as
unsigned
I will have only 127 values (so my program will to store more blocks of mem) or the UTF-8 change to negative too?
Sorry if I can't explain it correctly, but I think that i is a bit complex.
NOTE:
Thanks for all answer
I don't understand how it is interpreted normally.
I think that like ascii, if I have a signed and unsigned char on my program, the strings have diferently values, and it leads to confuse, imagine it in utf8 so.
I've had a couple requests to explain a comment I made.
The fact that a char type can default to either a signed or unsigned type can be significant when you're comparing characters and expect a certain ordering. In particular, UTF8 uses the high bit (assuming that char is an 8-bit type, which is true in the vast majority of platforms) to indicate that a character code point requires more than one byte to be represented.
A quick and dirty example of the problem:
#include <stdio.h>
int main( void)
{
signed char flag = 0xf0;
unsigned char uflag = 0xf0;
if (flag < (signed char) 'z') {
printf( "flag is smaller than 'z'\n");
}
else {
printf( "flag is larger than 'z'\n");
}
if (uflag < (unsigned char) 'z') {
printf( "uflag is smaller than 'z'\n");
}
else {
printf( "uflag is larger than 'z'\n");
}
return 0;
}
On most projects that I work, the unadorned char type is typically avoided in favor us using a typedef that explicitly specifies an unsigned char. Something like the uint8_t from stdint.h or
typedef unsigned char u8;
Generally dealing with an unsigned char type seems to work well and have few problems - the one area that I have seen occasional problems is when using something of that type to control a loop:
while (uchar_var-- >= 0) {
// infinite loop...
}
Two things:
Whether a char type is signed or unsigned won't affect your ability to translate UTF8-encoded-strings to and from whatever display string type you're using (WCHAR or whatnot). Don't worry about it, in other words: the UTF8 bytes are just bytes, and whatever you're using as an encoder/decoder will do the right thing.
Some of your confusion may be that you're trying to do this:
unsigned char *string = "This is a UTF8 string";
Don't do this-- you're mixing different concepts. A UTF-8 encoded string is just a sequence of bytes. C string literals (as above) were not really designed to represent this; they're designed to represent "ASCII-encoded" strings. Although for some cases (like mine here) they end up being the same thing, in your example in the question, they may not. And certainly in other cases they won't be. Load your Unicode strings from an external resource. In general I'd be wary of embedding non-ASCII characters in a .c source file; even if the compiler knows what to do with them, other software in your toolchain may not.
Using unsigned char has its pros and cons. The biggest benefits are that you don't get sign extension or other funny features such as signed overflow that would produce unexpected results from calculations. Unsigned char is also compatible with <cctype> macros/functions such as isalpha(ch) (all these require values in unsigned char range). On the other hand, all I/O functions require char*, requiring you to cast whenever you do I/O.
As for UTF-8, storing it in signed or unsigned arrays is fine but you have to be careful with those string literals as there is little guarantee about them being valid UTF-8. C++0x adds UTF-8 string literals to avoid possible issues and I would expect the next C standard to adopt those as well.
In general you should be fine, though, as long as you make sure that your source code files are always UTF-8 encoded.
signed / unsigned affect only arithmetic operations. if char is unsigned then higher values will be positive. in case of signed they will be negative. But range is same still.
Not really, unsigned / signed does not specify how many values a variable can hold. It specifies how they are interpreted.
So, an unsigned char has the same amount of values as a signed char, except that the one has negative numbers and the other doesn't. It is still 8 bits (if we assume that a char holds 8 bits, I'm not sure it does everywhere).
It makes no differences when using a char* as a string. The only time signed/unsigned would make a difference is if you would be interpreting it as a number, like for arithmetic or if you were to print it as an integer.
UTF-8 characters cannot be assumed to store in one byte. UTF-8 characters can be 1-4 bytes wide. So, a char, wchar_t, signed or unsigned would not be sufficient for assuming one unit can always store one UTF-8 character.
Most platforms (such as PHP, .NET, etc.) have you build strings normally (such as char[] in C) and you use a library to convert between encodings and parse characters out of the string.
As to you'r question:
think if I have a singed or unsigned ARRAY of chars can be it make my program run wrong? – drigoSkalWalker
Yes. Mine did. Heres a simple runnable excerpt from my app that totally comes out wrong if using ordinary signed chars.
Try running it after changing all chars to unsigned in parameters. Like this:
int is_valid(unsigned char c);
it should then work properly.
#include <stdio.h>
int is_valid(char c);
int main() {
char ch = 0xFE;
int ans = is_valid(ch);
printf("%d", ans);
}
int is_valid(char c) {
if((c == 0xFF) || (c == 0xFE)) {
printf("NOT valid\n");
return 0;
}
else {
printf("valid\n")
return 1;
}
}
What it does is validate if the char is a valid byte within utf-8.
0xFF and 0xFE are NOT valid bytes in utf-8.
imagine the problem if the function validates it as a valid byte?
what happens is this:
0xFE
=
11111110
=
254
If you save this in a ordinary char (that is signed) the leftmost bit, most significant bit, makes it negative. But what negative number is it?
It does this by flipping the bits and adding one bit.
11111110
00000001
00000001 + 00000001 =
00000010 = 2
and remember it made it negative, so it becomes -2
so (-2 == 0xFE) in the function ofcourse isnt true.
same goes for (-2 == 0xFF).
So a function that checks for invalid bytes ends up validating unvalid bytes as if they are ok :-o.
Two other reasons I can think of to stick to unsigned when dealing with utf-8 is:
If you might need some bitshifting to the right, there can be trouble because then you might end up adding 1's from the left if using signed chars.
utf-8 and unicode only uses positive numbers so... why dont you as well? keeping it simple :)

Resources