20

I'm trying to create a neatly formatted table on C++ by setting the width of the different fields. I can use setw(n), doing something like

cout << setw(10) << x << setw(10) << y << endl;

or change ios_base::width

cout.width (10);
cout << x;
cout.width (10);
cout << y << endl;

The problem is, neither of the alternatives allows me to set a default minimum width, and I have to change it everytime I'll write something to the stream.

Does anybody knows a way I can do it without having to repeat the same call countless times? Thanks in advance.

Andre Manoel
  • 301
  • 1
  • 2
  • 6
  • possible duplicate of [Effective use of C++ iomanip library](http://stackoverflow.com/questions/5328411/effective-use-of-c-iomanip-library) or maybe http://stackoverflow.com/questions/405039/permanent-stdsetw – Robᵩ Aug 30 '11 at 19:29
  • 1
    Related to the stickiness of various iomanip manipulators. setw is NOT sticky: http://stackoverflow.com/questions/1532640/which-iomanip-manipulators-are-sticky – Gnawme Aug 30 '11 at 19:45
  • Ok, sorry. I have looked for something similar before, but without success. The answers here and in the others posts gave me a good grasp of how I can solve it, thanks. – Andre Manoel Aug 30 '11 at 19:45
  • 1
    If you can, you should use _Boost.Format_. Look at the [answer from Herb Sutter to the question 'C++ alignment when printing cout <<'](http://stackoverflow.com/questions/2485963/c-alignment-when-printing-cout/2486085#2486085) – Christian Ammer Aug 30 '11 at 20:19
  • A work round is here: http://stackoverflow.com/a/37495361/984471 – Manohar Reddy Poreddy May 28 '16 at 05:04

3 Answers3

21

You can create an object that overloads operator<< and contains an iostream object that will automatically call setw internally. For instance:

class formatted_output
{
    private:
        int width;
        ostream& stream_obj;

    public:
        formatted_output(ostream& obj, int w): width(w), stream_obj(obj) {}

        template<typename T>
        formatted_output& operator<<(const T& output)
        {
            stream_obj << setw(width) << output;

            return *this;
        }

        formatted_output& operator<<(ostream& (*func)(ostream&))
        {
            func(stream_obj);
            return *this;
        }
};

You can now call it like the following:

formatted_output field_output(cout, 10);
field_output << x << y << endl;
Jason
  • 31,834
  • 7
  • 59
  • 78
  • 3
    +1, thanks! In case anyone else is interested: the second `operator<<` defined above allows the class to deal with functions such as `std::endl`, as described [here](http://stackoverflow.com/questions/1134388/stdendl-is-of-unknown-type-when-overloading-operator). Hope this helps any other curious cats who are picking apart @Jason's code... – GnomeDePlume Jan 02 '14 at 16:26
1

I know this is still making the same call, but I know of no other solution from what I am getting from your question.

#define COUT std::cout.width(10);std::cout<<

int main()
{
    std::cout.fill( '.' );

    COUT "foo" << std::endl;
    COUT "bar" << std::endl;

    return 0;
}

Output:

..........foo
..........bar
ssell
  • 6,429
  • 2
  • 34
  • 49
0

why not just create a function?

pseudocode e.g.

void format_cout(text, w) {
 cout << text << width(w);
}

That's a bit scrappy but hopefully you get the idea.

Ray
  • 617
  • 8
  • 15