How to Pad an Int With Leading Zeros When Using Cout ≪≪ Operator

Print leading zeros with C++ output operator?

This will do the trick, at least for non-negative numbers(a) such as the ZIP codes(b) mentioned in your question.

#include <iostream>
#include <iomanip>

using namespace std;
cout << setw(5) << setfill('0') << zipCode << endl;

// or use this if you don't like 'using namespace std;'
std::cout << std::setw(5) << std::setfill('0') << zipCode << std::endl;

The most common IO manipulators that control padding are:

  • std::setw(width) sets the width of the field.
  • std::setfill(fillchar) sets the fill character.
  • std::setiosflags(align) sets the alignment, where align is ios::left or ios::right.

And just on your preference for using <<, I'd strongly suggest you look into the fmt library (see https://github.com/fmtlib/fmt). This has been a great addition to our toolkit for formatting stuff and is much nicer than massively length stream pipelines, allowing you to do things like:

cout << fmt::format("{:05d}", zipCode);

And it's currently being targeted by LEWG toward C++20 as well, meaning it will hopefully be a base part of the language at that point (or almost certainly later if it doesn't quite sneak in).


(a) If you do need to handle negative numbers, you can use std::internal as follows:

cout << internal << setw(5) << setfill('0') << zipCode << endl;

This places the fill character between the sign and the magnitude.


(b) This ("all ZIP codes are non-negative") is an assumption on my part but a reasonably safe one, I'd warrant :-)

How can I pad a float with leading zeros when using cout operator

Combine std::setw, std::setfill, std::fixed and std::setprecision:

std::cout << std::setfill('0') << std::setw(5) 
<< std::fixed << std::setprecision(2) << x;

So, the value for setw is: 2 for the precision desired + 2 for the integer desired + 1 for the floating point.

Note: x = 107.1224 will be outputted as 107.12.

Printing zero-padded hex with std::cout

I suppose you can write a "stream manipulator". This is useful if you have multiple hex numbers you want to print in this format. This is clearly not an ideal solution, but using a wrapper type you can make your own "format flag" to toggle it. See Sticky custom stream manipulator for more information.

#include <iostream>
#include <iomanip>

static int const index = std::ios_base::xalloc();

std::ostream& hexify(std::ostream& stream) {
stream.iword(index) = 1;
return stream;
}

std::ostream& nohexify(std::ostream& stream) {
stream.iword(index) = 0;
return stream;
}

struct WrapperType {
uint32_t _m;
public:
WrapperType(uint32_t m) : _m(m)
{
}

uint32_t getm() const
{
return _m;
}
};
std::ostream& operator<< (std::ostream& os, const WrapperType& t) {
if (os.iword(index))
return os << "0x" << std::hex << std::setw(8) << std::setfill('0') << t.getm();
else
return os << t.getm();
}

int main()
{
WrapperType my_int{0xabcd};
std::cout << hexify << my_int << my_int;
std::cout << nohexify << my_int;
}

How can I print 0x0a instead of 0xa using cout?

This works for me in GCC:

#include  <iostream>
#include <iomanip>

using namespace std;

int main()
{
cout << "0x" << setfill('0') << setw(2) << right << hex << 10 << endl;
}

If you are getting sick and tired of iostream's formatting quirkiness, give Boost.Format a try. It allows good-old-fashioned, printf-style format specifiers, yet it is type-safe.

#include <iostream>
#include <boost/format.hpp>

int main()
{
std::cout << boost::format("0x%02x\n") % 10;
}

UPDATE (2019)

Check out the {fmt} library that's been accepted into C++20. Benchmarks show it to be faster than Boost.Format.

#if __has_include(<format>)
#include <format>
using std::format;
#else
#include <fmt/format.h>
using fmt::format;
#endif

std::cout << format("{:#04x}\n", 10);

Right shift with zeros at the beginning

This is how C and binary arithmetic both work:

If you left shift 0xff << 3, you get binary: 00000000 11111111 << 3 = 00000111 11111000

If you right shift 0xff >> 3, you get binary: 00000000 11111111 >> 3 = 00000000 00011111

0xff is a (signed) int with the positive value 255. Since it is positive, the outcome of shifting it is well-defined behavior in both C and C++. It will not do any arithmetic shifts nor any kind or poorly-defined behavior.

#include <stdio.h>

int main()
{

printf("%.4X %d\n", 0xff << 3, 0xff << 3);
printf("%.4X %d\n", 0xff >> 3, 0xff >> 3);

}

Output:

07F8 2040
001F 31

So you are doing something strange in your program because it doesn't work as expected. Perhaps you are using char variables or C++ character literals.


Source: ISO 9899:2011 6.5.7.


EDIT after question update

int number = ~0; gives you a negative number equivalent to -1, assuming two's complement.

number = number << 4; invokes undefined behavior, since you left shift a negative number. The program implements undefined behavior correctly, since it either does something or nothing at all. It may print fffffff0 or it may print a pink elephant, or it may format the hard drive.

number = number >> 4; invokes implementation-defined behavior. In your case, your compiler preserves the sign bit. This is known as arithmetic shift, and arithmetic right shift works in such a way that the MSB is filled with whatever bit value it had before the shift. So if you have a negative number, you will experience that the program is "shifting in ones".

In 99% of all real world cases, it doesn't make sense to use bitwise operators on signed numbers. Therefore, always ensure that you are using unsigned numbers, and that none of the dangerous implicit conversion rules in C/C++ transforms them into signed numbers (for more info about dangerous conversions, see "the integer promotion rules" and "the usual arithmetic conversions", plenty of good info about those on SO).

EDIT 2, some info from the C99 standard's rationale document V5.10:

6.5.7 Bitwise shift operators

The description of shift operators in K&R suggests that shifting by a
long count should force the left operand to be widened to long before
being shifted. A more intuitive practice, endorsed by the C89
Committee, is that the type of the shift count has no bearing on the
type of the result.

QUIET CHANGE IN C89

Shifting by a long count no longer coerces the shifted operand to
long. The C89 Committee affirmed the freedom in implementation granted
by K&R in not requiring the signed right shift operation to sign
extend, since such a requirement might slow down fast code and since
the usefulness of sign extended shifts is marginal. (Shifting a
negative two’s complement integer arithmetically right one place is
not the same as dividing by two!)

Is it possible to store a leading zero in an int?

An int basically stores leading zeros. The problem that you are running into is that you are not printing the leading zeros that are there.

Another, different approach is to create a function that will accept the four int values along with a string and to then return a string with the numbers.

With this approach you have a helper function with very good cohesion, no side effects, reusable where you need something similar to be done.

For instance:

char *joinedIntString (char *pBuff, int int1, int int2, int int3, int int4)
{
pBuff[0] = (int1 % 10) + '0';
pBuff[1] = (int2 % 10) + '0';
pBuff[2] = (int3 % 10) + '0';
pBuff[3] = (int4 % 10) + '0';
pBuff[4] = 0; // end of string needed.
return pBuff;
}

Then in the place where you need to print the value you can just call the function with the arguments and the provided character buffer and then just print the character buffer.

With this approach if you have some unreasonable numbers that end up have more than one leading zero, you will get all of the zeros.

Or you may want to have a function that combines the four ints into a single int and then another function that will print the combined int with leading zeros.

int createJoinedInt (int int1, int int2, int int3, int int4)
{
return (int1 % 10) * 1000 + (int2 % 10) * 100 + (int 3 % 10) * 10 + (int4 % 10);
}

char *joinedIntString (char *pBuff, int joinedInt)
{
pBuff[0] = ((joinedInt / 1000) % 10) + '0';
pBuff[1] = ((joinedInt / 100) % 10) + '0';
pBuff[2] = ((joinedInt / 10) % 10) + '0';
pBuff[3] = (joinedInt % 10) + '0';
pBuff[4] = 0; // end of string needed.
return pBuff;
}

Pad leading zeroes in multiples of x, using std::cout std::hex

How about this:

template <typename Int>
struct Padme
{
static_assert(std::is_unsigned<Int>::value, "Unsigned ints only");

Int n_;
explicit Padme(Int n) : n_(n) {}

template <typename Char, typename CTraits>
friend
std::basic_ostream<Char, CTraits> & operator<<(
std::basic_ostream<Char, CTraits> & os, Padme p)
{
return os << std::setw(ComputeWidth(p.n_)) << p.n_;
}

static std::size_t ComputeWidth(Int n)
{
if (n < 0x10000) { return 4; }
if (n < 0x100000000) { return 8; }
if (n < 0x1000000000000) { return 12; }
return 16;
}
};

template <typename Int>
Padme<Int> pad(Int n) { return Padme<Int>(n); }

Usage:

std::cout << pad(129u) << "\n";

With some more work you could provide versions with different digit group sizes, different number bases etc. And for signed types you could stick std::make_unsigned into the pad function template.

How to print __int128 in g++?

If you don't need any of the fancy formatting options, writing
your own << operator is trivial. Formally, I suspect that
writing one for __int128_t would be considered undefined
behavior, but practically, I think it would work, up until the
library starts providing actual support for it (at which point,
you'd retire your conversion operator).

Anyway, something like the following should work:

std::ostream&
operator<<( std::ostream& dest, __int128_t value )
{
std::ostream::sentry s( dest );
if ( s ) {
__uint128_t tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do
{
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}

Note that this is just a quicky, temporary fix, until the time
the g++ library supports the type. It counts on 2's complement,
wrap around on overflow, for __int128_t, but I'd be very
surprised if that wasn't the case (formally, it's undefined
behavior). If not, you'll need to fix up the initialization of
tmp. And of course, it doesn't handle any of the formatting
options; you can add as desired. (Handling padding and the
adjustfield correctly can be non-trivial.)



Related Topics



Leave a reply



Submit