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?
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
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.
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
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
Essayez d'utiliser le manipulateur Setw. Veuillez consulter http://www.cplusplus.com/reference/iostream/manipulators/setw/ pour plus d'informations
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;
}