Hi all!

I have a little problem here, I would like the width function in cout applied to all the sucesive outputs. However, it is only applied to the next output only, I mean, with this code I get

0:00:10:20:30:4
1:01:11:21:31:4
2:02:12:22:32:4
3:03:13:23:33:4
4:04:14:24:34:4
5:05:15:25:35:4
6:06:16:26:36:4
7:07:17:27:37:4
8:08:18:28:38:4
9:09:19:29:39:4

and I would like
0:0 0:1 0:2 0:3 0:4
1:0 1:1 1:2 1:3 1:4
2:0 2:1 2:2 2:3 2:4
3:0 3:1 3:2 3:3 3:4
4:0 4:1 4:2 4:3 4:4
5:0 5:1 5:2 5:3 5:4
6:0 6:1 6:2 6:3 6:4
7:0 7:1 7:2 7:3 7:4
8:0 8:1 8:2 8:3 8:4
9:0 9:1 9:2 9:3 9:4

#include <iostream>

using namespace std;

int main(void)
{
  cout.width(8);
  cout.setf(std::ios::fixed | std::ios::right);
  for (int row = 0; row < 10; ++row) {
    for (int column = 0; column < 5; ++column) {
      cout << row << ":" << column;
    }
    cout << endl;
  }
  return 0;
}

I realize that by moving the cout.width inside the loop but do the trick in this example, but not in one without a loop resulting in having to specify the width in every output.

My question is, is there a way in which the width function applies to everything that goes after it?

Thank you in advance!

Dani AI

Generated

You cannot make the stream’s field width “sticky.” Both cout.width() and std::setw set the width for the next formatted insertion only; after that insertion, the stream resets the width back to 0. That is why your output runs together. is right about setw, and is right that you need some form of wrapper if you want it applied automatically. This behavior is by design. (en.cppreference.com)

Two tidy ways to get the grid you want without sprinkling width/setw everywhere:

  • Modern C++20+: build each cell as a string and pad it with std::format, which has its own width/alignment independent of iostream state.
#include <format>
#include <iostream>

for (int r = 0; r < 10; ++r) {
    for (int c = 0; c < 5; ++c)
        std::cout << std::format("{:>8}", std::format("{}:{}", r, c));
    std::cout << '\n';
}

This avoids fiddling with the stream entirely. See std::format and its width/alignment spec. (cppreference.com)

  • Pre-C++20 (streams only): centralize the width once by defining a tiny type and operator<< that applies std::setw internally. Callers just stream a Cell, and every insertion is padded as a single unit (similar spirit to ’s functor).
#include <iomanip>
#include <sstream>

struct Cell { int r, c; };

std::ostream& operator<<(std::ostream& os, const Cell& x) {
    std::ostringstream tmp;
    tmp << x.r << ':' << x.c;           // build one token
    return os << std::right << std::setw(8) << tmp.str();
}

// usage
for (int r = 0; r < 10; ++r) {
    for (int c = 0; c < 5; ++c) std::cout << Cell{r, c};
    std::cout << '\n';
}

Tip: alignment (std::left/std::right) and fill (std::setfill) persist; width does not, so keep the width call inside your wrapper. (en.cppreference.com)

Recommended Answers

All 5 Replies

Stream manipulator "setw" in <iomanip>

The setw manipulator has the same problem. It only affects the next output operation.
AFAIK, there is no way you can avoid setting the width over and over again.
Maybe someone else knows better though. Here's a simple hackish solution:

#include <iostream>
#include <sstream>

using namespace std;

class ostream_w : public ostream
{
    unsigned w;

public:

    ostream_w(ostream & os_, unsigned w_): w(w_)
    {
        rdbuf(os_.rdbuf());
    }

    template <class T>
    ostream_w & operator << (const T & t)
    {
        width(w);

        static_cast<ostream &>(*this) << t;

        return *this;
    }

    // necessary for endl
    ostream_w & operator << (ostream & (*pf)(ostream &))
    {
        pf(static_cast<ostream &>(*this));

        return *this;
    }
};

int main()
{
    ostream_w cout_w6(cout, 6);

    cout_w6.setf(ios::right);

    for (int row = 0; row <= 12; ++row)
    {
        for (int column = 0; column <= 10; ++column)
        {
            stringstream buffer;

            buffer << row << ":" << column;

            cout_w6 << buffer.str();
        }

        cout_w6 << endl;
    }

    return 0;
}

Stream manipulator "setw" in <iomanip>

Unfortunatelly it has the same behaviour, it only applies to the following output

any idea?

If I modify your code to use an object to do the output instead of putting the code inline you still have to call the manipulator functions but they happen every time. Consider

struct Formatter {
    void operator()(int r, int c) {
        std::cout.width(8);
        std::cout.setf(std::ios::fixed | std::ios::right);
        std::cout << r << ':' << c;
    }
};

int main(void)
{
  Formatter format;
  for (int row = 0; row < 10; ++row) {
    for (int column = 0; column < 5; ++column) {
        format(row,column);
    }
    std::cout << std::endl;
  }
  return 0;
}

I see...

I think I will have to use one of those workarounds you have propossed

I always learn when I ask things here!

Thank you for all your answers!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.