Solved

convert to hexadecimal

Posted on 2013-11-09
6
295 Views
Last Modified: 2013-12-02
I am trying to understand how the runtime converts this to hex

	std::stringstream s;
        s << std::hex;    
	int i = 0;
        s << std::setw(2) << std::setfill('0') << (unsigned int)(unsigned char)a[i];      // WORKS
        s << std::setw(2) << std::setfill('0') << (unsigned int)a[i];     // DOES NOT WORK
        

Open in new window




1.  Why do we need this line
      s << std::hex;    

2) Why does it not work without (unsigned char)
0
Comment
Question by:perlperl
6 Comments
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 39635806
It's a stream manipulator. It coerces the stream to read its data as hexadecimal (where as the default is decimal). You could certainly read the data as a string first, and then do the conversion to hexadecimal value, but this would take a bit more code.

As to why it does not work without (unsigned char), what is the type of your a array?
0
 

Author Comment

by:perlperl
ID: 39635832
The array was void* and passed to this function as const char*
0
 
LVL 86

Expert Comment

by:jkr
ID: 39635841
You could use a 'unsigned int*' cast since it is an array, e.g.

        s << std::setw(2) << std::setfill('0') << ((unsigned int*)a)[i];

Open in new window

0
Efficient way to get backups off site to Azure

This user guide provides instructions on how to deploy and configure both a StoneFly Scale Out NAS Enterprise Cloud Drive virtual machine and Veeam Cloud Connect in the Microsoft Azure Cloud.

 

Author Comment

by:perlperl
ID: 39636407
Thanks jkr. that works too
but I am trying to understand my solution as why
this works   (unsigned int)(unsigned char)
and why this not    (unsigned int)a
0
 
LVL 86

Accepted Solution

by:
jkr earned 250 total points
ID: 39636429
>>but I am trying to understand my solution as why
>>this works   (unsigned int)(unsigned char)

This only works because you are printing 2-digit hexadecimal expressions that consist of one byte only. That will fail for values that consist of more than one byte..

Basically, you are casting 'void a[x]' to 'unsigned char' first. OK, that's fine. The next cast makes it clear to the stringstream that you want an unsigned int to be printed, so the single byte taken from 'a[ix]' (as a char) is taken and converted.
0
 
LVL 33

Assisted Solution

by:sarabande
sarabande earned 250 total points
ID: 39639402
2) Why does it not work without (unsigned char)
there are two reasons:
- a void pointer points to unknown type. in order to calculate the address where a[ i ] is  located by "a + (i * sizeof(a[ 0 ])"  the compiler needs to know the size of a single element of the array.

 - an unsigned int is 32-bit while unsigned char is 8-bit. so omitting the unsigned char would cause 4 bytes to be converted to an integer, what gives wrong numbers.

note, my compiler does not accept the cast you posted as "works" cause a[ i ]  still has an undefined size (the cast only determines the wished output of the a[ i ] but not the type of the array) and the address of a[ i ] cannot correctly calculated, because of that.

to solve the issue correctly you need to cast the void pointer to a byte pointer (see also code of jkr above). when the compiler knows the type of the pointer, operations like + or [] will compile properly.


unsigned char x[] = { 33, 34, 35, 36 };
void * a = x;
std::cout << (unsigned int)(*(unsigned char*)a+i);

Open in new window


the final cast to unsigned int is necessary to get the right operator<< selected which takes an int or unsigned int. otherwise the operator<<(std::ostream&, unsigned char) was used, which would not evaluate the std::hex manipulator, but would print the character code associated to the byte code.

to make all the code simpler you may use a byte buffer (pointer to unsigned char) instead of a void pointer as early as possible.

unsigned char * pbuf = (unsigned char *)getData();
...
std::cout << std::hex << std::setw(2) << std::right << std::setfill('0') << (int)pbuf[i];

Open in new window


it also needs two casts, but is much better readable.

Sara
0

Featured Post

ScreenConnect 6.0 Free Trial

Want empowering updates? You're in the right place! Discover new features in ScreenConnect 6.0, based on partner feedback, to keep you business operating smoothly and optimally (the way it should be). Explore all of the extras and enhancements for yourself!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

778 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question