How to output unsigned/signed char or ty

2019-05-20 05:16发布

问题:

Background:

I have template stream operators (e.g. operator << (ostream &, std::vector <T>)) (that output container elements that may possibly be of some 8-bit integer type, (e.g. unsigned char, int_least8_t, et cetera).

Problem:

Default is that these types are output as char (ASCII). I only used char (or wchar_t or whatever) for ASCII variables, never unsigned/signed types. How do I get these other 8-bit types to always be output as signed int / unsigned int (numbers) instead, even when the caller doesn't know the type?

First tries:

I have tried (with GCC) for example defining operator << (ostream &, unsigned char) with a cast in it (i.e. stream << static_cast <int> (value). That works for unsigned char values, but then uint8_t still gets output as a char.

The same underlying type (i.e. unsigned/signed char can not be used in overloads, so I can't define an overload of for example operator << (ostream &, int_fast8_t).

回答1:

One way that comes to mind is using type traits to define the output type for each type. You would have to declare that for every type by hand. The traits could be defined as a template struct that is specialized for every data-type that has a different output-type than the data-type itself:

template< T >
struct output_trait {
    typedef const T & output_type;
}

In your operator you write:

std::cout << static_cast< output_trait< T >::output_type >( variable ) << std::endl;

This will do no cast by default, but for types for which output_trait is specialized it will do a cast:

template<>
struct output_trait< unsigned char > {
    typedef unsigned int output_type;
}


回答2:

You're confusing the actual data held in a variable, with whatever representation you choose for printing it.

Think of it this way: chars, ints, doubles, longs, whatevers, they're all just chunks of memory for you to store numbers in. A char is a number between 0 and 255 (or -128 and 127) -- you can choose to represent it as an ASCII character, or as a number, or as stars in the sky with the aid of OpenGL.

If you want to see the number behind the character 'a', just instruct your program to treat that chunk of memory (that for you contains an 'a') as a number. Use casts. Here:

http://www.cplusplus.com/doc/tutorial/typecasting/

See if that helps!



回答3:

You can simply cast it:

#include<iostream>

int main()
{
 uint8_t blah = 65;
 std::cout << static_cast<int>(blah) << "\n";
 return 0;
}

65



回答4:

If I have understood you right.. output it like this:

std::cout << ( unsigned int )char << '\n';

Or more c++ style - use static_cast, for example:

int main()
{
    char a = 'a';
    char b = 97;
    std::cout << static_cast< unsigned int >( a ) << '\n';
    std::cout << static_cast< unsigned int >( b ) << '\n';
    return 0;
}

both std::cout will print the same: the first one - the ASCII code of 'a': 97, the second one - just the value 97, stored in b. Both, a and b, are absolutely the same.



回答5:

You can cast them before you output them:

std::cout << (unsigned int) container[index];