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.

drescherjm
  • 10,365
  • 5
  • 44
  • 64
user3716193
  • 476
  • 5
  • 21

2 Answers2

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:~$
Leonardo Herrera
  • 8,388
  • 5
  • 36
  • 66
  • 2
    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`. – M.M Jun 19 '18 at 22:05
  • 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? – Leonardo Herrera Jun 20 '18 at 03:22
  • It will produce the same result regardless of the system endianness – M.M Jun 20 '18 at 04:11
  • 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? – Leonardo Herrera Jun 20 '18 at 06:28
  • 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 – M.M Jun 20 '18 at 21:31
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...

Zeta
  • 913
  • 10
  • 24
  • 2
    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++ – M.M Jun 19 '18 at 22:07
  • 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.. – Zeta Jun 19 '18 at 22:19
  • The other posted answer is close to being complete – M.M Jun 19 '18 at 22:22
  • 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." – M.M Jun 19 '18 at 22:32
  • This is a basiic union usage.. In fact I don't know any compiler that will generate undefined behavior. Can you name one? – Zeta Jun 19 '18 at 22:45
  • undefined behaviour is specified by the C++ Standard, not by compilers . Working as expected is one possible manifestation of undefined behaviour, so you could say that all compilers exhibit UB – M.M Jun 19 '18 at 22:51
  • You are going to write a thesis about this.. Just see the idea of my code. Let's wrap this. – Zeta Jun 19 '18 at 22:57
  • The issue here is that `union` is a different beast in C++ than what it was in C. In C it did work as expected; in C++ the behaviour is indeed undefined, although most compilers do the sane thing (type punning). [More details in this StackOverflow question](https://stackoverflow.com/questions/25664848/unions-and-type-punning). – Leonardo Herrera Jun 20 '18 at 03:02