Printing chars as Integers
Asked Answered
M

4

9

I want to control whether my ostream outputting of chars 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?

Microphysics answered 8/6, 2012 at 14:5 Comment(8)
Do you want always to print chars as integers or depending on a condition?Trio
I want it to depend on a condition (state) similar to the ios state flags.Liggitt
I don't understand the necessity to distinguish signed and unsigned char. If you want to output it as a number, cast it as an int first. Otherwise, just print it to os.Roentgenogram
Maybe it is possible to write your own io manipulator for this...Braley
cout << static_cast<uint32_t>(some_char_val);?Mendelsohn
@JohnDibling: static_cast should be used when type and precision is known in advance but not in generic template algorithms, which is what I want this for. We could type cast everything to uint64_t to minimize risk of overflow but what if argument is an arbitrary precision integer or some other class no convertible to uintxx_t?Liggitt
You said this was for chars and unsigned chars.Mendelsohn
@JohnDibling: Ohh, sorry about that.Liggitt
A
1

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.

Abubekr answered 8/6, 2012 at 14:42 Comment(0)
A
1

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;
}

Credit: How can I print a char as a number? How can I print a char* so the output shows the pointer’s numeric value?


Works for both signed/unsigned char:

Antonietta answered 14/1, 2016 at 15:26 Comment(0)
T
0

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;
  }
Trio answered 8/6, 2012 at 14:28 Comment(1)
You realize of course that you wrote 23 lines of code (excluding tester) in order to be able to print a character as a number, right? Isn't this a bit overkill?Roentgenogram
K
0

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.

Kahlil answered 16/12, 2020 at 16:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.