22

在 C++ 代码中,我有一个双变量矩阵,可以打印出来。但是,因为它们都有不同的位数,所以输出格式被破坏了。一种解决方案是这样做, cout.precision(5)但我希望不同的列具有不同的精度。此外,由于在某些情况下存在负值,因此-符号的存在也会导致问题。如何解决这个问题并产生格式正确的输出?

4

6 回答 6

20

Off the top of my head, you can use setw(int) to specify the width of the output.

like this:

std::cout << std::setw(5) << 0.2 << std::setw(10) << 123456 << std::endl;
std::cout << std::setw(5) << 0.12 << std::setw(10) << 123456789 << std::endl;

gives this:

    0.2    123456
   0.12 123456789
于 2012-06-27T12:36:48.113 回答
16

正如其他人所说,关键是使用机械手。他们忽略了说的是您通常使用自己编写的操纵器。一个FFmt操纵器(对应F于 Fortran 中的格式相当简单:

class FFmt
{
    int myWidth;
    int myPrecision;
public:
    FFmt( int width, int precision )
        : myWidth( width )
        , myPrecision( precision )
    {
    }

    friend std::ostream& 
    operator<<( std::ostream& dest, FFmt const& fmt )
    {
        dest.setf( std::ios_base::fixed, std::ios_base::formatfield );
        dest.precision( myPrecision );
        dest.width( myWidth );
        return dest;
    }
};

这样,您可以为每一列定义一个变量,例如:

FFmt col1( 8, 2 );
FFmt col2( 6, 3 );
//  ...

和写:

std::cout  << col1 << value1
    << ' ' << col2 << value2...

一般来说,除了在最简单的程序中,您可能不应该使用标准操纵器,而应该使用基于您的应用程序的自定义操纵器;例如temperaturepressure如果这是你处理的那种事情。通过这种方式,您在代码中很清楚您正在格式化什么,如果客户突然要求再增加一位压力,您就知道在哪里进行更改。

于 2012-06-27T12:55:12.230 回答
8

使用机械手

从这里的示例:

#include <iostream>
#include <iomanip>
#include <locale>
int main()
{
    std::cout.imbue(std::locale("en_US.utf8"));
    std::cout << "Left fill:\n" << std::left << std::setfill('*')
              << std::setw(12) << -1.23  << '\n'
              << std::setw(12) << std::hex << std::showbase << 42 << '\n'
              << std::setw(12) << std::put_money(123, true) << "\n\n";

    std::cout << "Internal fill:\n" << std::internal
              << std::setw(12) << -1.23  << '\n'
              << std::setw(12) << 42 << '\n'
              << std::setw(12) << std::put_money(123, true) << "\n\n";

    std::cout << "Right fill:\n" << std::right
              << std::setw(12) << -1.23  << '\n'
              << std::setw(12) << 42 << '\n'
              << std::setw(12) << std::put_money(123, true) << '\n';
}

输出:

Left fill:
-1.23*******
0x2a********
USD *1.23***

Internal fill:
-*******1.23
0x********2a
USD ****1.23

Right fill:
*******-1.23
********0x2a
***USD *1.23
于 2012-06-27T12:33:27.337 回答
3

看看流操纵器,尤其是std::setwstd::setfill

float f = 3.1415926535;
std::cout << std::setprecision(5)   // precision of floating point output
          << std::setfill(' ')      // character used to fill the column
          << std::setw(20)          // width of column
          << f << '\n';             // your number
于 2012-06-27T12:34:13.623 回答
0

尝试使用 setw 操纵器。请参阅http://www.cplusplus.com/reference/iostream/manipulators/setw/了解更多信息

于 2012-06-27T12:34:46.490 回答
0

有一种使用 i/o 操纵器的方法,但我觉得它很笨拙。我只想写一个这样的函数:

template<typename T>
std::string RightAligned(int size, const T & val)
{
    std::string x = boost::lexical_cast<std::string>(val);
    if (x.size() < size)
        x = std::string(size - x.size(), ' ') + x;
    return x;
}
于 2012-06-27T12:34:55.183 回答