83
#include <iostream> using namespace std; int main() { char c1 = 0xab; signed char c2 = 0xcd; unsigned char c3 = 0xef; cout << hex; cout << c1 << endl; cout << c2 << endl; cout << c3 << endl; } 

I expected the output are as follows:

ab cd ef 

Yet, I got nothing.

I guess this is because cout always treats 'char', 'signed char', and 'unsigned char' as characters rather than 8-bit integers. However, 'char', 'signed char', and 'unsigned char' are all integral types.

So my question is: How to output a character as an integer through cout?

PS: static_cast(...) is ugly and needs more work to trim extra bits.

5
  • afaik, casting is the most effective way... (e.g. static_cast<int>()) Commented Feb 1, 2013 at 10:55
  • 1
    btw. the only reason you need to resort to "trimming" is that you are clearly not using the types correctly (the first two clearly overflows) and this is what you get as a result. If you always used the correct type, then the cast is simply, static_cast<unsigned>(...)... Commented Feb 1, 2013 at 11:10
  • 2
    There is also the option of cout << +c1; Commented Feb 1, 2013 at 11:23
  • @Nim where do you see any overflow? There's even no arithmetic going here, the values assigned are just 0xffffffab and 0xffffffcd on systems with 32 bit two's complement ints, and are then casted to smaller chars, which fit them perfectly due to the nature of two's complement representation. Commented Jul 24, 2015 at 7:27
  • @Ruslan there is no 0xffffffab and 0xffffffcd here, but 0xab and 0xcd are too big for signed char, maximum value for signed char is 0x7f. Yes bit representation allows you that, but it's platform dependent, what actually you get. Not all platforms are using compliment of two. Commented Sep 21, 2019 at 6:53

6 Answers 6

185
char a = 0xab; cout << +a; // promotes a to a type printable as a number, regardless of type. 

This works as long as the type provides a unary + operator with ordinary semantics. If you are defining a class that represents a number, to provide a unary + operator with canonical semantics, create an operator+() that simply returns *this either by value or by reference-to-const.

source: Parashift.com - How can I print a char as a number? How can I print a char* so the output shows the pointer's numeric value?

Sign up to request clarification or add additional context in comments.

7 Comments

This is rather obfuscated. A simple static_cast as in sheu's answer clearly conveys the intend.
why is this the most upvoted answer. it is so much more obscure that a simple cast eg: (int)
Yes, it is obscure, but is very useful in generic code.
Came here for exactly this problem: properly emitting values from a templated numeric type. Ideally, there's be a more explicit operator, like valueOf or perhaps a stream modifier, but in the absense of these, the unary plus work across all numeric types. Regarding the trickiness of this syntax, this is precisely why languages include comments, and I strongly suggest this warrants a short comment.
|
10

Cast them to an integer type, (and bitmask appropriately!) i.e.:

#include <iostream> using namespace std; int main() { char c1 = 0xab; signed char c2 = 0xcd; unsigned char c3 = 0xef; cout << hex; cout << (static_cast<int>(c1) & 0xFF) << endl; cout << (static_cast<int>(c2) & 0xFF) << endl; cout << (static_cast<unsigned int>(c3) & 0xFF) << endl; } 

3 Comments

And the output of c1 and c2 is ffffffab and ffffffcd, which is not what the OP expected.
However, 'char', 'signed char', and 'unsigned char' are all integral types. static_cast(...) is ugly and needs more work to trim extra bits.
@xmllmx: ostream also has overloads that print the char types as their character representations -- not what the poster wants,
7

Maybe this:

char c = 0xab; std::cout << (int)c; 

Hope it helps.

2 Comments

char is an unsigned integer. Casting it to int can show weird values. Better to cast to uint8_t.
Not really, uint8_t is alias. Its actual underlying type is unsinged char Also signage of char platform specific, hence the usage of types unsinged char and signed char
2

Another way is to overload the << operator:

#include <iostream> using namespace std; typedef basic_ostream<char, char_traits<char>> basicOstream; /*inline*/ basicOstream &operator<<(basicOstream &stream, char c) { return stream.operator<<(+c); } /*inline*/ basicOstream &operator<<(basicOstream &stream, signed char c) { return stream.operator<<(+c); } /*inline*/ basicOstream &operator<<(basicOstream &stream, unsigned char c) { return stream.operator<<(+c); } int main() { char var1 = 10; signed char var2 = 11; unsigned char var3 = 12; cout << var1 << endl; cout << var2 << endl; cout << var3 << endl; return 0; } 

which prints the following output:

10 11 12 Process finished with exit code 0 

I think it's very neat and useful. hope it hepls!


And Also if you want it to print a hex value you can do like this:

basicOstream &operator<<(basicOstream &stream, char c) { return stream.operator<<(hex).operator<<(c); } // and so on... 

Comments

1

What about:

char c1 = 0xab; std::cout << int{ c1 } << std::endl; 

It's concise and safe, and produces the same machine code as other methods.

Comments

0

Another way to do it is with std::hex apart from casting (int):

std::cout << std::hex << (int)myVar << std::endl; 

I hope it helps.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.