Convert to Hex Problem

I

Immortal Nephi

I choose 8-bit datatype as char when I want to work integer from 0 to
255 ranges. I don't need large integer numbers like short and long.
My question is why do cout output symbol characters instead of hex
digits. Look at cout << " Byte Hex--" .... below. How can you fix
error?
I am aware that char can only show characters, letters, numbers, etc
on range 31 to 127 and symbol characters on range 128 to 255. I don't
want to print characters. I prefer to print hex digits from 0 through
F. Please help. Thanks...


unsigned char byte = 0xB4;
unsigned short word = 0x4F2C;
unsigned long dword = 0x12FA07BC;

cout << " Byte Hex-->" << showbase << internal << setw(10) << setfill
( '0' ) << hex << byte << endl;
cout << " Word Hex-->" << showbase << internal << setw(10) << setfill
( '0' ) << hex << word << endl;
cout << "DWord Hex-->" << showbase << internal << setw(10) << setfill
( '0' ) << hex << dword << endl;
 
J

Jonathan Lee

 How can you fix error?

Well, it's not really an error. When you << a char to cout, it thinks
you want to print the corresponding character. Ex., if your char
contains
(decimal) 65, you'll print out 'A'.

(Assuming ASCII for the sake of argument.)

To get around this, just up-cast to an int for the cout operation.
i.e.,
instead of
cout << ... << byte << endl;
use
cout << ... << static_cast<unsigned>(byte) << endl;

--Jonathan
 
C

Christopher Dearlove

Jonathan Lee said:
Well, it's not really an error.

It's a poor piece of specification. char should print e.g. A, but signed
char and unsigned char should have been specified to print values, as
they are separate types, and should be used for small numerucal values.

But that's water under the bridge, and we are where we are. You can
explicitly upcast, and I used to. But safer (because it works even when
the type isn't a char type, and therefore can be used in templates) is to
use the unary plus operator

cout << +byte;

which works because that does integral promotion.

(It is, I think, the only place I use unary plus.)
 
J

Juha Nieminen

Immortal said:
I don't
want to print characters. I prefer to print hex digits from 0 through
F.

Your request is completely contradictory. In the first sentence you
say that you *don't* want to print any characters, while in the second
sentence you say that you *do* want to print some characters (namely
characters between 0 and F). Thus giving you an answer is impossible.

Make your question unambiguous.
 
R

Rolf Magnus

Immortal said:
I choose 8-bit datatype as char when I want to work integer from 0 to
255 ranges. I don't need large integer numbers like short and long.

So having a smaller datatype is important enough to you to accept their
reduced performance on typical 32 bit systems?
My question is why do cout output symbol characters instead of hex
digits.

Because that's how it's defined.
Look at cout << " Byte Hex--" .... below. How can you fix
error?

Convert the value to int before printing it.
 
J

Jorgen Grahn

So having a smaller datatype is important enough to you to accept their
reduced performance on typical 32 bit systems?

If he has a lot of them stored in vectors or arrays, the lower memory
usage probably makes up for that. (Assuming what you write is even
true. Seems to me a decent compiler would translate to 32-bit
arithmetic if that was really faster.)

But yeah, I *do* think people use char and unsigned char for
arithmetics too often.

/Jorgen
 
J

Jorgen Grahn

I don't
want to print characters. I prefer to print hex digits from 0 through
F. Please help. Thanks...


unsigned char byte = 0xB4;
unsigned short word = 0x4F2C;
unsigned long dword = 0x12FA07BC;

cout << " Byte Hex-->" << showbase << internal << setw(10) << setfill
( '0' ) << hex << byte << endl;
cout << " Word Hex-->" << showbase << internal << setw(10) << setfill
( '0' ) << hex << word << endl;
cout << "DWord Hex-->" << showbase << internal << setw(10) << setfill
( '0' ) << hex << dword << endl;

Ugh. Write a class with wraps the unsigned char, and prints as hex:

struct Foo {
explicit Foo(unsigned char val);
// ...
};
std::eek:stream& operator<< (std::eek:stream& os, const Foo& val);

cout << " Byte Hex-->" << Foo('0') << '\n';
cout << " Word Hex-->" << Foo('0') << '\n';
cout << " DWord Hex-->" << Foo('0') << '\n';

And when you have done that, it is immediately obvious that you print
the same value all three times. Before, it was lost in noise.

/Jorgen
 
J

Juha Nieminen

Hendrik said:
Doing so he'll have the problem that a 'cout << foo' might
mess up the stream without any indication. (Of course, there
are ways to automatically undo such changes to streams, but
it is hard to imagine someone who is struggling to output a
byte in hex to accomplish this.)

For reference, this is an easy way of storing the state of an output
stream before making changes to it, and then restoring that state:

std::ios::fmtflags flags = std::cout.flags();

// change the format flags of std::cout and output your data here

std::cout.flags(flags);
 
J

James Kanze

For reference, this is an easy way of storing the state of an
output stream before making changes to it, and then restoring
that state:
std::ios::fmtflags flags = std::cout.flags();
// change the format flags of std::cout and output your data here
std::cout.flags(flags);

There's more state than just the flags, and you also have to
restore it in case of an exception. I use two different
solutions, depending on context:

-- An IOSave class, initialized with a stream. The class saves
all of the state (except width and error codes), and
restores it in the destructor. (A while back, Jean-Marc
Bourget suggested that I use copyfmt to do this. This would
require a bit of care in order to ensure exception safety,
if someone was playing around with the exception mask, but
would ensure copy of any state allocated with ios::xalloc,
which is otherwise impossible to handle.)

-- Manipulators which save the state, and restore it in the
destructor. I have a base class which does this if the
manipulator derives from it, and all of my manipulators
derive from it, so all of my manipulators do this.

The IOSave class, at least in its simplest form (ignoring
allocated state) should be within the possibilities of almost
any C++ programmer; it's really just a very simple application
of RAII. The state saving manipulator is a bit trickier,
because the order of destruction may not be the same as the
order of invocation of the << operators.
 
J

Jorgen Grahn

Jorgen said:
[...]

Ugh. Write a class with wraps the unsigned char, and prints as hex:

struct Foo {
explicit Foo(unsigned char val);
// ...
};
std::eek:stream& operator<< (std::eek:stream& os, const Foo& val);

cout << " Byte Hex-->" << Foo('0') << '\n';
cout << " Word Hex-->" << Foo('0') << '\n';
cout << " DWord Hex-->" << Foo('0') << '\n';

Doing so he'll have the problem that a 'cout << foo' might
mess up the stream without any indication.

Oops, I forgot about that. Or never learned it properly, to be
truthful.
(Of course, there
are ways to automatically undo such changes to streams, but
it is hard to imagine someone who is struggling to output a
byte in hex to accomplish this.)

:-( Those ways should be easy to use. Surely that's what I want, when
I implement output of my MC68k emulator Address class -- I want to
output as eight-digit hex, but I don't want to affect what someone else
may print a few milliseconds later.

On the other hand, I often implement my operator<< using sprintf. I
know it by heart, and in this case you can often predict how large the
buffer needs to be. And of course, it doesn't affect any stream state
-- you end up pushing a C string onto the stream.

/Jorgen
 
J

James Kanze

Jorgen said:
]
Ugh. Write a class with wraps the unsigned char, and prints as hex:
struct Foo {
explicit Foo(unsigned char val);
// ...
};
std::eek:stream& operator<< (std::eek:stream& os, const Foo& val);
cout << " Byte Hex-->" << Foo('0') << '\n';
cout << " Word Hex-->" << Foo('0') << '\n';
cout << " DWord Hex-->" << Foo('0') << '\n';
Doing so he'll have the problem that a 'cout << foo' might
mess up the stream without any indication.
Oops, I forgot about that. Or never learned it properly, to be
truthful.
:-( Those ways should be easy to use. Surely that's what I
want, when I implement output of my MC68k emulator Address
class -- I want to output as eight-digit hex, but I don't want
to affect what someone else may print a few milliseconds
later.

You might want to check out StateSavingManip in the IO subsystem
of my library: http://kanze.james.neuf.fr/code-en.html. (If you
don't want to build and link in the entire library, the header
and the implementation file are in fact fairly
autonomous---about all you'd have to change is with regards to
namespaces.) Basically, to write a manipulator, all you do is
derive from the class, overriding the pure virtual function
setState to set whatever options you want; the base class takes
care of the rest (template method pattern).
On the other hand, I often implement my operator<< using
sprintf. I know it by heart, and in this case you can often
predict how large the buffer needs to be. And of course, it
doesn't affect any stream state -- you end up pushing a C
string onto the stream.

My experience is that such predictions concerning the size often
end up wrong later, as other things in the code evolve. But you
can do the same thing using std::eek:stringstream.
 
J

Jorgen Grahn

Jorgen said:
Jorgen Grahn wrote:
[...]

Ugh. Write a class with wraps the unsigned char, and prints as hex:

struct Foo {
explicit Foo(unsigned char val);
// ...
};
std::eek:stream& operator<< (std::eek:stream& os, const Foo& val);

cout << " Byte Hex-->" << Foo('0') << '\n';
cout << " Word Hex-->" << Foo('0') << '\n';
cout << " DWord Hex-->" << Foo('0') << '\n';
Doing so he'll have the problem that a 'cout << foo' might
mess up the stream without any indication.

[...]

On the other hand, I often implement my operator<< using sprintf. [...]

What's wrong with using a 'std::eek:stringstream' instead?

It is a lot heavier than sprintf() into a char array on stack, and I
have to deal with setw(), std::hex et al instead of the printf-style
format strings I know by heart (from using them in C, Perl and
Python).

But yes, with the std::eek:stringstream step I do not have to care about
resetting the stream state properly -- that takes away most of the
complexity of the iomanip stuff.

/Jorgen
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top