C++中的cout如何对齐输出数字

5
#include <iostream>

using namespace std;

int main()
{
    cout << -0.152454345 << " " << -0.7545 << endl;
    cout << 0.15243 << " " << 0.9154878774 << endl;
}

输出:

-0.152454 -0.7545
0.15243 0.915488

我希望输出的结果如下:

我想让输出看起来像这样:

-0.152454 -0.754500
 0.152430  0.915488

我的解决方案:

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
    cout << fixed << setprecision(6) << setw(9) << setfill(' ') << -0.152454345 << " ";
    cout << fixed << setprecision(6) << setw(9) << setfill(' ') << -0.7545 << endl;
    cout << fixed << setprecision(6) << setw(9) << setfill(' ') << 0.15243 << " ";
    cout << fixed << setprecision(6) << setw(9) << setfill(' ') << 0.9154878774 << endl;
}

输出结果不错,但代码写的很糟糕。有什么可以做的吗? 这是我的代码:https://ideone.com/6MKd31

2
使用 stdio.h。iostream 对于格式化不好。 - llllllllll
你可以为此编写一个函数吗? - Galik
1
一个很好的指南,解释了数字格式化的基础知识,并展示了好的代码示例: https://websites.umich.edu/~eecs381/handouts/formatting.pdf - Roland
5个回答

5
指定输出格式总是很糟糕的。无论如何,您可以省略重复那些跨输入/输出保持不变的流修饰符,并仅重复临时的那些(setw):
// change state of the stream
cout << fixed << setprecision(6) << setfill(' ');
// output data
cout << setw(9) << -0.152454345  << " ";
cout << setw(9) << -0.7545       << endl;
cout << setw(9) << 0.15243       << " ";
cout << setw(9) <<  0.9154878774 << endl;

@Aconcagua 为什么这么说? - Jean-Baptiste Yunès

3
这可能不是你想要的,但我认为还是把它提供出来,因为这个方法很简单。如果你可以容忍非负数前面有一个加号,那么你可以使用以下代码:
std::cout << std::showpos << /*ToDo - the rest of your output here*/

至少这样一切都能对齐,而且只需最小的努力。


2
有点“死后回帖”,但对未来的某个人可能仍然有用。我们可以使用lambda表达式(或等效函数)使格式化更加轻松。
#include <iostream>
#include <iomanip>

int main()
{
  using namespace std;

  auto format = [](std::ostream &os) -> std::ostream& {
    return os << fixed << setprecision(6) << setw(9) << setfill(' ');
  };


  cout << format << -0.152454345 << " " << format << -0.7545      << "\n";
  cout << format << 0.15243      << " " << format << 0.9154878774 << endl;
}

输出:

-0.152454 -0.754500
 0.152430  0.915488

聪明,我喜欢学习lambda,所以+1,但我现在不会用它来格式化。 - Roland

2

曾经在处理流的时候遇到了类似的问题(尽管更为复杂),您可以使用单独的格式化对象来避免重复代码:

class F
{
    double v;
public:
    F(double v) : v(v) { };
    friend ostream& operator<<(ostream& s, F f)
    {
        s << setw(9) << v;
    }
};

使用方法:

std::cout << fixed << setprecision(6) << setfill(' '); // retained, see Jean's answer
std::cout << F(12.10) << ' ' << F(-10.12) << std::endl;

根据您的需求和使用频率,这可能过于复杂或不够 - 请自行决定...


2
你可以为它编写一个函数:
std::ostream& format_out(std::ostream& os, int precision, int width, char fill, double value)
{
    return os << std::fixed << std::setprecision(precision) << std::setw(width) << std::setfill(fill)
        << value;
}

int main()
{
    format_out(std::cout, 6, 9, ' ', -0.152454345) << '\n';
    format_out(std::cout, 6, 9, ' ', -0.7545) << '\n';
    format_out(std::cout, 6, 9, ' ', 0.15243) << '\n';
    format_out(std::cout, 6, 9, ' ', 0.9154878774) << '\n';
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接