Solved

convert to hexadecimal

Posted on 2013-11-09
6
299 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
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
SendMessage fails while PostMessage works 2 122
C++ finding a sting in a char* string from a text file 3 120
Unresolved External Symbols 3 103
computer science syllabus 3 88
Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

856 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