ahgert
ahgert

Reputation: 75

iomanip with an object of a class

In a C++ program I have some code to print an object of a class called fraction. Its variables are n (the numerator), d (the denominator) and sinal (signal: true when a fraction is positive and false otherwise).

ostream &operator << (ostream &os, const fraction &x){//n=0

    if(!x.sinal)
        os << "-";

    os << x.n;

    if(x.d!=1 && x.n!=0)
        os << "/" << x.d;

    return os;
}

It does a good job, but when I try to use a setw() in it, it doesn't work properly: it just affects the first item to be printed (whether it's the signal or the numerator).

I tried to change it and the solution I found was first to convert it to a string and then using the os with a iomanip:

ostream &operator << (ostream &os, const fraction &x){//n=0

    string xd, xn;

    stringstream ssn;
    ssn << x.n;
    ssn >> xn;

    stringstream ssd;
    ssd << x.d;
    ssd >> xd;

    string sfra = "";

    if(!x.sinal)
        sfra += "-";

    sfra += xn;

    if(x.d !=1 && x.n != 0){
        sfra += "/";
        sfra += xd;
    }

    os << setw (7) << left << sfra;

    return os;
}

This works, but obviously I'm not able to change the width that a fraction will have: it will be 7 for all of them. Is there a way to change that? I really need to use different widths for different fractions. Thanks in advance.

Upvotes: 6

Views: 229

Answers (1)

MicroVirus
MicroVirus

Reputation: 5487

That's because, as per https://stackoverflow.com/a/1533752 , the width of the output is explicitly reset for each formatted output.

What you could do is at the start of your function get the current width, which is the width set by std::setw (or related), and then set this width explicitly for each value where you want it applied and use std::setw(0) for each value that you want to output as-is:

ostream &operator << (ostream &os, const fraction &x)
{
    std::streamsize width = os.width();

    if(!x.sinal)
        os << std::setw(width) << "-";
    else
        os << std::setw(width); // Not necessary, but for explicitness.

    os << x.n;

    if(x.d!=1 && x.n!=0)
        os << "/" << std::setw(width) << x.d;

    return os;
}

Now you need to improve upon this a bit to handle left and right padding; this only handles left-padding.

Upvotes: 1

Related Questions