Tux

...making Linux just a little more fun!

C++'s cout and hexadecimal output

René Pfeiffer [lynx at luchs.at]


Thu, 26 Jun 2008 01:16:04 +0200

Hello, Gang!

I am trying to compute a SHA1 hash inside a C++ program without linking to additional libraries. There are some SHA1 code snippets around and they seem to work. So far so good. In order to compare SHA1 sums it's nice to have them in hexadecimal representation. The SHA1 code I used holds the sum in a byte array which is basically an array of unsigned chars. Creating hexadecimal output can be done as follows:

// Filename:  hex_output.cc - cout test firing range
 
#include <iomanip>
#include <ios>
#include <iostream>
 
#include <stdlib.h>
 
using namespace std;
 
int main(int argc, char **argv) {
    unsigned char array[10];
    unsigned short i;
 
    // An array with a French accent (sorry, SCNR)
    array[0] =3D 'A';
    array[1] =3D 'L';
    array[2] =3D 'L';
    array[3] =3D 'o';
    array[4] =3D ' ';
    array[5] =3D 'O';
    array[6] =3D 'r';
    array[7] =3D 'l';
    array[8] =3D 'd';
    array[9] =3D '!';
    for( i=3D0; i<10; i++) {
        cout << hex << setfill('0') << setw(2) << nouppercase << array[i];
    }
    cout << endl << endl;
    return(0);
}

Unfortunately this outputs: 0A0L0L0o0 0O0r0l0d0!

As soon as I change the cout line to

cout << hex << setfill('0') << setw(2) << nouppercase << (unsigned short)array[i];

it works and produces: 414c4c6f204f726c6421

It's late and I still lack my good night coffee, but why is that? I didn't expect this behaviour.

Best, René.


Top    Back


Jimmy O'Regan [joregan at gmail.com]


Thu, 26 Jun 2008 03:18:23 +0100

2008/6/26 René Pfeiffer <lynx@luchs.at>:

> Hello, Gang!
>
> I am trying to compute a SHA1 hash inside a C++ program without linking
> to additional libraries. There are some SHA1 code snippets around and
> they seem to work. So far so good. In order to compare SHA1 sums it's
> nice to have them in hexadecimal representation. The SHA1 code I used
> holds the sum in a byte array which is basically an array of unsigned
> chars. Creating hexadecimal output can be done as follows:
>
> // Filename:  hex_output.cc - cout test firing range
>
> #include <iomanip>
> #include <ios>
> #include <iostream>
>
> #include <stdlib.h>
>
> using namespace std;
>
> int main(int argc, char **argv) {
>    unsigned char array[10];
>    unsigned short i;
>
>    // An array with a French accent (sorry, SCNR)
>    array[0] = 'A';
>    array[1] = 'L';
>    array[2] = 'L';
>    array[3] = 'o';
>    array[4] = ' ';
>    array[5] = 'O';
>    array[6] = 'r';
>    array[7] = 'l';
>    array[8] = 'd';
>    array[9] = '!';
>    for( i=0; i<10; i++) {
>        cout << hex << setfill('0') << setw(2) << nouppercase << array[i];
>    }
>    cout << endl << endl;
>    return(0);
> }
>

Break it down even more:

#include <ios>
#include <iostream>
 
using namespace std;
 
int main ()
{
        cout << hex << 'a';
}
 
Output: a
> Unfortunately this outputs: 0A0L0L0o0 0O0r0l0d0!
>
> As soon as I change the cout line to
>
> cout << hex << setfill('0') << setw(2) << nouppercase << (unsigned short)array[i];
>
> it works and produces: 414c4c6f204f726c6421
>
> It's late and I still lack my good night coffee, but why is that? I
> didn't expect this behaviour.
>

'hex' is only defined to take an integer; because it's a stream modifier, the only reasonable thing for it to do when it encounters input it can't process is to output it unmodified.


Top    Back


Jimmy O'Regan [joregan at gmail.com]


Thu, 26 Jun 2008 03:31:21 +0100

2008/6/26 Jimmy O'Regan <joregan@gmail.com>:

> 2008/6/26 René Pfeiffer <lynx@luchs.at>:
>> It's late and I still lack my good night coffee, but why is that? I
>> didn't expect this behaviour.
>>
>
> 'hex' is only defined to take an integer; because it's a stream
> modifier, the only reasonable thing for it to do when it encounters
> input it can't process is to output it unmodified.
>
#include <ios>
#include <iostream>
 
using namespace std;
 
int main ()
{
        cout << hex << "maybe desirable: " << 32;
}
 
output: maybe desirable: 20


Top    Back


René Pfeiffer [lynx at luchs.at]


Thu, 26 Jun 2008 10:27:43 +0200

On Jun 26, 2008 at 0331 +0100, Jimmy O'Regan appeared and said:

> 2008/6/26 Jimmy O'Regan <joregan@gmail.com>:
> > 2008/6/26 René Pfeiffer <lynx@luchs.at>:
> >> It's late and I still lack my good night coffee, but why is that? I
> >> didn't expect this behaviour.
> >
> > 'hex' is only defined to take an integer; because it's a stream
> > modifier, the only reasonable thing for it to do when it encounters
> > input it can't process is to output it unmodified.
> >
>
> #include <ios>
> #include <iostream>
>
> using namespace std;
>
> int main ()
> {
>         cout << hex << "maybe desirable: " << 32;
> }
>
> output: maybe desirable: 20

Ok, I didn't think of that. Now it makes sense. The problem is that most examples I found turn a hex string into an integer and other examples just state "use hex" and use integer types.

Thanks, René.


Top    Back