6

Couldn't find help online. Is there any way to work around this issue?

std::showbase only adds a prefix (for example, 0x in case of std::hex) for non-zero numbers (as explained here). I want an output formatted with 0x0, instead of 0.

However, just using: std::cout << std::hex << "0x" << .... is not an option, because the right hand side arguments might not always be integers (or equivalents). I am looking for a showbase replacement, which will prefix 0 with 0x and not distort non-ints (or equivalents), like so:

using namespace std;

/* Desired result: */
cout << showbase << hex << "here is 20 in hex: " << 20 << endl; // here is 20 in hex: 0x14

/* Undesired result: */
cout << hex << "0x" << "here is 20 in hex: " << 20 << endl;     // 0xhere is 20 in hex: 20

/* Undesired result: */
cout << showbase << hex << "here is 0 in hex: " << 0 << endl;   // here is 0 in hex: 0

thanks a lot.

alonbe
  • 73
  • 5
  • It really is a bit odd. Even though you use a `hex` prefix, the `0` is still printed in *octal*. :-) [Is 0 a decimal literal or an octal literal?](http://stackoverflow.com/questions/6895522/is-0-a-decimal-literal-or-an-octal-literal) – Bo Persson Aug 26 '15 at 12:46
  • i'm not sure i understood you question, but it's a const int& ... the fact that it is not printed as a `hex`, is just the definition of `std::showbase` as explained in the link that i put in the OP – alonbe Aug 27 '15 at 11:31
  • It was an insider joke about the fact that, accordning to the grammar, `0` is an octal number. And you get that even when you explicitly ask for it in hex. – Bo Persson Aug 27 '15 at 13:57
  • This would seem to be a bug? If you explicitly set the base to 16 (`std::hex`) then `std::showbase` would be expected to comply. You just identified a problem that was dragging me down the rabbit hole. – jwm Jul 31 '18 at 23:00
  • oh, and printf trips people up too... https://stackoverflow.com/a/14733899/9220132 – jwm Jul 31 '18 at 23:01

1 Answers1

2

try

std::cout << "here is 20 in hex: " << "0x" << std::noshowbase << std::hex << 20 << std::endl;

This way number will be prefixed with 0x always, but you will have to add << "0x" before every number printed.

You can even try to create your own stream manipulator

struct HexWithZeroTag { } hexwithzero;
inline ostream& operator<<(ostream& out, const HexWithZeroTag&)
{
  return out << "0x" << std::noshowbase << std::hex;
}

// usage:
cout << hexwithzero << 20;

To keep setting between operator<< call, use answer from here to extend your own stream. You would have to change locale's do_put like this:

const std::ios_base::fmtflags reqFlags = (std::ios_base::showbase | std::ios_base::hex);

iter_type 
do_put(iter_type s, ios_base& f, char_type fill, long v) const {
     if (v == 0 && ((f.flags() & reqFlags) == reqFlags)) {
        *(s++) = '0';
        *(s++) = 'x';
    }
    return num_put<char>::do_put(s, f, fill, v);
} 

Complete working solution: http://ideone.com/VGclTi

Community
  • 1
  • 1
Hcorg
  • 11,598
  • 3
  • 31
  • 36