Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String formatting (c++)

Tags:

c++

I tried to format output strings in my console application (like a table)

cout <<  "\n\n-----------------\n";
cout << setw(8) << left << "F\t|";
cout << setw(8) << left << "x\t|";
cout <<  "\n-----------------\n";
//...
cout.width(8);
cout.setf(ios::left);
cout << fixed << setprecision(3) << F << "\t|";

cout.width(8);
cout.setf(ios::left);
cout << x << "\t|";
cout <<  "\n-----------------\n\n";

But as result my output looks like this
enter image description here
What's wrong with my upper string formatting?

like image 540
Heidel Avatar asked Feb 04 '26 18:02

Heidel


2 Answers

I used the same code as you did and got the same output until I removed the \t at the end of the line. See the new code:

cout <<  "\n\n-----------------\n";
cout << setw(8) << left << "F\t|";
cout << setw(8) << left << "x\t|";
cout <<  "\n-----------------\n";
//...
cout.width(8);
cout.setf(ios::left);
cout << fixed << setprecision(3) << F << "|";

cout.width(8);
cout.setf(ios::left);
cout << x << "|";
cout <<  "\n-----------------\n\n";
like image 156
MasterPlanMan Avatar answered Feb 06 '26 08:02

MasterPlanMan


As already noted, it's the tabs that are causing the problem.

I would not stop at just removing the tabs though. As it stands right now, your code is highly repetitive and next to impossible to maintain. I'd do a (nearly) complete rewrite, with a couple of functions to cut down on the repetition. My first cut would probably look something like this:

// format a value in a field of specified width, followed by a separator
template <class T>
string field(T val, int w, char sep = '|') {
    stringstream b;
    b << setw(w) << left << fixed << setprecision(3) << val << sep;
    return b.str();
}

// generate a separator for a specified number of fields,
// each of a specified width
string sep(int c, int w, char val = '-') {
    string s(c * (w + 1), val);
    return string("\n") + s + "\n";
}

int main() {
    static const int w = 8;
    double F = 1.234, x = 3.45;
    string s = sep(2, w);

    cout << "\n" << s;
    cout << field("F", w) << field("x", w) << s;
    cout << field(F, w) << field(x, w) << s;
}

Seems to me that this makes the code rather more readable and quite a bit more maintainable. For example, if we decided to display an a and b on the next line, it would seem fairly obvious to add something like:

cout << field(a, w) << field(b, w) << s;

...and we wouldn't have to look very hard to be pretty sure it was going to match up with the previous line. Likewise, if we wanted to change a column width, etc.

like image 22
Jerry Coffin Avatar answered Feb 06 '26 07:02

Jerry Coffin