web-dev-qa-db-fra.com

Formatage de la sortie en C ++

Dans un code C++, j'ai une matrice de variables doubles que j'imprime. Cependant, comme tous ont un nombre différent de chiffres, le format de sortie est détruit. Une solution consiste à faire cout.precision(5) mais je veux que les différentes colonnes aient une précision différente. De plus, comme il existe des valeurs négatives dans certains cas, la présence de - signe provoque également des problèmes. Comment contourner cela et produire une sortie correctement formatée?

18
lovespeed

Sur le dessus de ma tête, vous pouvez utiliser setw (int) pour spécifier la largeur de la sortie.

comme ça:

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;

donne ceci:

    0.2    123456
   0.12 123456789
14
stanri

La clé est, comme d'autres l'ont dit, d'utiliser des manipulateurs. Ce qu'ils ont négligé de dire, c'est que vous utilisez normalement des manipulateurs que vous écrivez vous-même. Un manipulateur FFmt (qui correspond au format F dans Fortran est assez simple:

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

De cette façon, vous pouvez définir une variable pour chaque colonne, par exemple:

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

et écrire:

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

En général, sauf dans les programmes les plus simples, vous ne devriez probablement pas utiliser les manipulateurs standard, mais plutôt des manipulateurs personnalisés basés sur votre application; par exemple. temperature et pressure si c'est le genre de chose que vous traitez. De cette façon, il est clair dans le code ce que vous formatez, et si le client demande soudainement un chiffre de plus dans la pression, vous savez exactement où faire le changement.

15
James Kanze

Utilisez manipulateurs .

De l'échantillon ici :

#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';
}

Production:

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

Jetez un oeil à stream manipulateurs , en particulier std::setw et 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

Essayez d'utiliser le manipulateur Setw. Veuillez consulter http://www.cplusplus.com/reference/iostream/manipulators/setw/ pour plus d'informations

0
Premkumar U

Il existe un moyen d'utiliser des manipulateurs d'E/S, mais je le trouve difficile à manier. Je voudrais juste écrire une fonction comme celle-ci:

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
Benjamin Lindley