Reputation: 12138
I want to control whether my ostream
outputting of char
s and unsigned char
's via <<
writes them as characters or integers. I can't find such an option in the standard library. For now I have reverted to using multiple overloads on a set of alternative print functions
ostream& show(ostream& os, char s) { return os << static_cast<int>(s); }
ostream& show(ostream& os, unsigned char s) { return os << static_cast<int>(s); }
Is there a better way?
Upvotes: 9
Views: 2363
Reputation: 12506
Just an update to an old post. The actual trick is using '+'. Eg:
template <typename T>
void my_super_function(T x)
{
// ...
std::cout << +x << '\n'; // promotes x to a type printable as a number, regardless of type
// ...
}
In C++11 you could do:
template <typename T>
auto promote_to_printable_integer_type(T i) -> decltype(+i)
{
return +i;
}
Works for both signed/unsigned char:
Upvotes: 1
Reputation: 55564
In C++20 you'll be able to use std::format
to do this:
unsigned char uc = 42;
std::cout << std::format("{:d}", uc); // format uc as integer 42 (the default)
std::cout << std::format("{:c}", uc); // format uc as char '*' (assuming ASCII)
In the meantime you can use the {fmt} library, std::format
is based on.
Disclaimer: I'm the author of {fmt} and C++20 std::format
.
Upvotes: 0
Reputation: 35188
No, there isn't a better way. A better way would take the form of a custom stream manipulator, like std::hex
. Then you could turn your integer printing off and on without having to specify it for each number. But custom manipulators operate on the stream itself, and there aren't any format flags to do what you want. I suppose you could write your own stream, but that's way more work than you're doing now.
Honestly, your best bet is to see if your text editor has functions for making static_cast<int>
easier to type. I assume you'd otherwise type it a lot or you wouldn't be asking. That way someone who reads your code knows exactly what you mean (i.e., printing a char as an integer) without having to look up the definition of a custom function.
Upvotes: 1
Reputation: 8604
I have a suggestion based on the technique used in how do I print an unsigned char as hex in c++ using ostream?.
template <typename Char>
struct Formatter
{
Char c;
Formatter(Char _c) : c(_c) { }
bool PrintAsNumber() const
{
// implement your condition here
}
};
template <typename Char>
std::ostream& operator<<(std::ostream& o, const Formatter<Char>& _fmt)
{
if (_fmt.PrintAsNumber())
return (o << static_cast<int>(_fmt.c));
else
return (o << _fmt.c);
}
template <typename Char>
Formatter<Char> fmt(Char _c)
{
return Formatter<Char>(_c);
}
void Test()
{
char a = 66;
std::cout << fmt(a) << std::endl;
}
Upvotes: 0