web-dev-qa-db-ja.com

C ++での出力のフォーマット

C++コードには、出力するdouble変数の行列があります。ただし、すべての桁数が異なるため、出力形式は破棄されます。 1つの解決策はcout.precision(5)を実行することですが、列ごとに精度を変えたいです。また、負の値が存在する場合があるため、-記号の存在も問題の原因になります。これを回避して適切にフォーマットされた出力を生成する方法は?

18
lovespeed

頭の上から、setw(int)を使用して出力の幅を指定できます。

このような:

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;

これを与える:

    0.2    123456
   0.12 123456789
14
stanri

他の人が言ったように、鍵はマニピュレータを使用することです。彼らが言うのを怠っていたのは、自分で書くマニピュレーターを通常使うということです。 FFmtマニピュレーター(FortranのF形式に対応)は非常に簡単です。

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それがあなたが扱っているようなものなら。このようにして、フォーマットする内容がコードで明確になり、クライアントがプレッシャーの中でもう1桁を要求した場合、どこで変更を行うかが正確にわかります。

15
James Kanze

manipulators を使用します。

サンプルから ここ

#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
6
John Dibling

ストリームを見てみましょう manipulators 、特にstd::setwおよびstd::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
1
jrok

Setwマニピュレータを使用してみてください。詳細については http://www.cplusplus.com/reference/iostream/manipulators/setw/ を参照してください

0
Premkumar U

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;
}
0