How to use setw with objects

1.1k views Asked by At

I'm trying to format output using the NTL library (a number theory library). One of the objects is the GF2X object, which is a polynomial represented as a string of coefficients. A quick example:

GF2X a = GF2X(5,1);
a++;
cout<<a;

will yield [1 0 0 0 0 1] which is the same as x^5 + 1. My question is about formatting this output using setw. I want to be able to output various length GF2X objects, prepended by a number, and appended with a string. I'd like my output to look like the following:

  1:    [x x x x x x x x]       string here
 15:    [x x x]                 string here

I would also settle for the right ] to be aligned, which is what I should probably expect if I'm using setw. However, when i use the code (variable names ommitted for simplicity):

    cout << setw(3)<< int <<": "<< setw(35) << GF2X << setw(15) << string << endl;

I get output more like this (some white space removed for compactness)

  1:            [x x x x x x x x]   string here
 15:            [x x x]   string here

In other words, the setw function seems to be treating the entire output of <<GF2X as a single character, and doesn't seem to actually account for the size of the output string. As you can see from the output I've shown you, the left side of the GF2X output is aligned, but the right side isn't, whereas typically, setw seems to align the right side of outputs.

2

There are 2 answers

3
Benjamin Lindley On BEST ANSWER

You can do it with a modification to the output operator. I imagine it's written something like this (I don't know anything about this GF2X class, so this is partially psuedo-code:

std::ostream & operator<<(std::ostream & os, const GF2X & x)
{
    os << '[';
    for (int i=0; i<x.num_elements; ++i)
        os << x.get_element(i) << ' ';
    return os << ']';
}

The problem is that setw will only operate on that first '[', it doesn't operate on the whole object (it doesn't know what the whole object is). You can fix the operator by writing the whole thing to a string (using stringstream or some other means), and then outputting the string. If modifying the operator is not an option for you, then you will need to use a separate helper function to first convert the object to a string (using a stringstream), then output that string to the stream.

Actually, boost::lexical_cast would come in really handy for you here, since it will do that last for you:

cout << setw(35) << boost::lexical_cast<std::string>(GF2X);
0
Teofrostus On

You can use a temporary ostringstream object to hold the output, and then use setw on the string provided (variable names omitted).

    ostringstream oss;
    oss << GF2X;
    cout << setw(3) << x << ": "<< setw(35) << oss.str() << setw(15) << string <<endl;

This formats the entire ostream object, rather than just the first character, and gives the proper output.