Question

As in c we can use various format specifiers like

  • %nd where n is a number, to print the number with a total of atleast n space covered
  • %0nd same as above, except pre-padding with 0's " %05d ",3 => 00003
  • %.nf to set precision of n after decimal
  • etc ....

So is there any way to use these with std::cout ?

I got some negative feedback in a recent course (c++ for c programmers) in coursera, for using printf instead of cout because i wanted to some formatting :(

Was it helpful?

Solution

For %nd %0nd, C++ equivalents are std::setw() and std::setfill().

#include <iostream>     // std::cout, std::endl
#include <iomanip>      // std::setfill, std::setw

int main () {
  std::cout << std::setfill ('x') << std::setw (10);
  std::cout << 77 << std::endl;
  return 0;
}

Output: xxxxxxxx77

%.nf can be replaced by std::setprecision and std::fixed,

#include <iostream>     // std::cout, std::fixed, std::scientific

int main () {
    double a = 3.1415926534;
    double b = 2006.0;
    double c = 1.0e-10;

    std::cout.precision(5);

    std::cout << "fixed:\n" << std::fixed;
    std::cout << a << '\n' << b << '\n' << c << '\n';
    return 0;
}

Output:

fixed:
3.14159
2006.00000
0.00000

OTHER TIPS

C++ streams don't use format-specifiers like C's printf()-type functions; they use manipulators.

For example:

#include <iostream>
#include <iomanip>


int main()
{
    std::cout << std::fixed << std::setprecision(6) << 42.0 << std::endl;
}

Output:

42.000000

See it run!

The usual solution in C++ is to defined manipulators which state what your trying to format, rather than to hack physical values directly at the point of output. (One possible exception is the width, where std::setw may be useful directly.) Thus, for example, when actually outputting something, you won't specify zero padding, or fixed, with 2 decimals, but something like:

std::cout << temperature(2) << theTemporature;

where temperature would be something like:

class temperature
{
    int myMinWidth;
public:
    temperature( int minWidth )
        : myMinWidth( minWidth )
    {
    }
    friend std::ostream& operator<<( std::ostream& dest, temperature const& manip )
    {
        dest.setf( std::ios_base::fixed, std::ios_base::floatfield );
        dest.precision( 2 );
        dest.width( myMinWidth );
        return dest;
    }
};

For the list of format modifications available, see the specification of std::ios_base, and the fields of std::ios_base::fmtflags.

If you're doing a lot of output, you might want to modify this to restore the original format flags at the end of the full expression. (All of the format information except the width is sticky, so forcing fixed format here leaves you with fixed format for the rest of the program, which isn't necessarily what you want.) I use the following as base class for all of my manipulators:

class StateSavingManip
{
public:
    void operator()( std::ios& stream ) const;
protected:
    StateSavingManip() : myStream( nullptr ) {}
    ~StateSavingManip();
private:
    virtual void setState( std::ios& stream ) const = 0;
private:
    mutable std::ios* myStream;
    mutable std::ios::fmtflags mySavedFlags;
    mutable int mySavedPrec;
    mutable char mySavedFill;
};

implementation:

namespace {
int getXAlloc() ;
int ourXAlloc = getXAlloc() + 1 ;

int
getXAlloc()
{
    if ( ourXAlloc == 0 ) {
        ourXAlloc = std::ios::xalloc() + 1 ;
        assert( ourXAlloc != 0 ) ;
    }
    return ourXAlloc - 1 ;
}
}

StateSavingManip::~StateSavingManip()
{
    if ( myStream != nullptr ) {
        myStream->flags( mySavedFlags ) ;
        myStream->precision( mySavedPrec ) ;
        myStream->fill( mySavedFill ) ;
        myStream->pword( getXAlloc() ) = NULL ;
    }
}

void
StateSavingManip::operator()( 
    std::ios&           stream ) const
{
    void*&              backptr = stream.pword( getXAlloc() ) ;
    if ( backptr == nullptr ) {
        backptr      = const_cast< StateSavingManip* >( this ) ;
        myStream     = &stream ;
        mySavedFlags = stream.flags() ;
        mySavedPrec  = stream.precision() ;
        mySavedFill  = stream.fill() ;
    }
    setState( stream ) ;
}

Note the use of the pword field to ensure that only the first temporary manipulator restores the format; the destructors will be called in the reverse order of construction, but the order of construction will typically not be specified if you have more than one such manipulator in an expression.

Finally: not everything is possible using this technique: if you want to systematically append a degree sign to the temperature, there's no way of doing so. In this case, you need to define a class Temperature, and overload the << operator for it; this allows everything imaginable (much more than you could ever achieve with printf style formatting).

C++ stream manipulators (iomanip) were specifically designed to support all of the standard c format specifiers operations, just with an entirely different interface. E.g. setfill and setw for the width and fill part of %02d.

Of course if you really need format strings (e.g. because it makes i18n easier for you), then you should have a look at boost::format, and if you have C++11 then you can easily write small variadic template wrapper around it, to make the format call look more like printf.

Whatever you do, please try to not use printf. It is not typesafe, and not extendible for output operations on user defined types.

There are stream manipulators, if you need them.
But I think you want to know this thing:
cout is smarter than printf(). Say you have:

int x = 34;
cout<<x;

Now the compiler will call:

ostream& operator<<(ostream& stream, int arg);

for you. And this function will print the output in console( since in your case stream is cout). The standard library supplies overloads for this << operator for all fundamental datatype available.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top