1

I have a char array of hex values and would like to convert them into a single integer value. I have two issues with the code I am currently using:

Problem 1: the value stored in strHex after running this is - "0927ffffffc0" when I want it to be "000927C0" - what is the reason for the extra "ffffff" being added?

Problem 2: I would like a solution to convert a char array of hex values to an integer without using stringstream if possible.

char cArray[4] = { 0x00, 0x09, 0x27, 0xC0 }; // (600000 in decimal)

std::stringstream ss;
for (int i = 0; i < 4; ++i)
{
    ss << std::hex << (int)cArray[i];
}
std::string strHex = ss.str();

int nHexNumber;
sscanf(strHex.c_str(), "%x", &nHexNumber);

nHexNumber should be 600000 when converted and its giving me -64.

11
  • Please only tag the language being used. Commented Jun 19, 2018 at 21:30
  • The "hex values" for the initialisation are irrelavant - each element is char but unsigned char would be better. Commented Jun 19, 2018 at 21:31
  • Use unsigned char instead of char Commented Jun 19, 2018 at 21:33
  • 1
    Why do you say that {0, 9, 39, 192} is "600,000" in decimal? Commented Jun 19, 2018 at 21:33
  • 2
    you are sign-extending the values when casting to int. 0xC0 is 10100000 in binary. Apparently char is considered to be a signed type, so when extending it to fit your 4-byte int type, it prepends a bunch of 1s to it to preserve the value rather than turn a negative number into a positive number by zero-extending. Commented Jun 19, 2018 at 21:41

2 Answers 2

3
#include <stdint.h>
#include <iostream>

int main(int argc, char *argv[]) {
        unsigned char cArray[4] = { 0x00, 0x09, 0x27, 0xC0 };
        uint32_t nHexNumber = (cArray[0] << 24) | (cArray[1] << 16) | (cArray[2] << 8) | (cArray[3]);

        std::cout << std::hex << nHexNumber << std::endl;
        return 0;
}

Edited: As pointed out by M.M this is not depending on endianness as originally stated.

Output under QEMU:

user@debian-powerpc:~$ uname -a
Linux debian-powerpc 3.2.0-4-powerpc #1 Debian 3.2.51-1 ppc GNU/Linux
user@debian-powerpc:~$ ./a.out
927c0
user@debian-powerpc:~$

Under Ubuntu on Windows:

leus@owl:~$ uname -a
Linux owl 4.4.0-43-Microsoft #1-Microsoft Wed Dec 31 14:42:53 PST 2014 x86_64 x86_64 x86_64 GNU/Linux
leus@owl:~$ ./a.out
927c0
leus@owl:~$
Sign up to request clarification or add additional context in comments.

5 Comments

This solution is NOT dependent on endianness. But it would be undefined behaviour if int is 16-bit, or if the high bit of cArray[0] is 1.
You have a good point about the first byte being 1, or int being 16 bits (or 64, for that matter). But why do you say this is endian-safe?
It will produce the same result regardless of the system endianness
Am I not putting the first byte in the fourth position, then the second in the third, the third in the second and the last byte in the first? How is that the resulting four bytes aren't ordered with the most significant byte last?
You're creating the value 600000 (in decimal) regardless of the representation. The code would have the same output on any endianness of 32-bit+ system
0
#include<arpa/inet.h>
#include<iostream>
using namespace std;

union {
    unsigned char cA[4] = { 0x00, 0x09, 0x27, 0xc0 };
    int k;
} u;

int main() 
{
    cout << htonl(u.k) << endl;
}

simple way is to use htonl...

8 Comments

In C++ it's undefined behaviour to read a union member that was not the last one written. Also htonl is not part of Standard C++
Then can you change this code to a complete code? It's better to give a productive advice than just to say it won't work..
The other posted answer is close to being complete
Maybe you should read your own link? It supports what I said in my first comment. "The lifetime of a union member begins when the member is made active. If another member was active previously, its lifetime ends." cA is active by virtue of being initialized, k is inactive and therefore you read a variable outside of its lifetime. Also see the very first line of the page, "A union is a special class type that can hold only one of its non-static data members at a time."
This is a basiic union usage.. In fact I don't know any compiler that will generate undefined behavior. Can you name one?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.