?
Solved

convert to hexadecimal

Posted on 2013-11-09
6
Medium Priority
?
311 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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 1000 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 35

Assisted Solution

by:sarabande
sarabande earned 1000 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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
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 additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

719 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