2012-06-27 33 views
12

En un código C++ tengo una matriz de variables dobles que imprimo. Sin embargo, debido a que todos ellos tienen diferentes números de dígitos, el formato de salida se destruye. Una solución es hacer cout.precision(5), pero quiero que las diferentes columnas tengan una precisión diferente. Además, como hay valores negativos en algunos casos, la presencia del signo - también causa problemas. ¿Cómo evitar esto y producir una salida con el formato correcto?Formato de salida en C++

Respuesta

10

De la parte superior de la cabeza, puede utilizar setw (int) para especificar el ancho de la salida.

así:

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; 

da esto:

0.2 123456 
    0.12 123456789 
+0

solo FYI: al hacer std :: setw (x) asegúrese de que x sea mayor que su precisión decimal. – solti

4

Use manipulators.

De la muestra here:

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

Salida:

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 
1

Tome un vistazo a la corriente manipulators, especialmente std::setw y 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 
0

Hay una manera de usar manipuladores de E/S, pero me resulta difícil de manejar. Me acaba de escribir una función como esta:

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

La clave es, como han dicho otros, a utilizar manipuladores. Lo que no mencionaron es que usted normalmente usa manipuladores que escribe usted mismo. Un FFmt manipulador (que se corresponde con el formato F en Fortran es bastante fácil:

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 esta manera, se puede definir una variable para cada columna, por ejemplo:

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

y escribir:

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

En general, excepto en los programas más simples, probablemente no sea utilizando el estándar manipuladores, sino manipuladores personalizados basados ​​en su aplicación; p.ej. temperature y pressure si ese es el tipo de que tiene que tratar. De esta forma, es claro en el código qué formato está , y si el cliente de repente pide un dígito más en la presión, usted sabe exactamente dónde realizar el cambio.

+0

Recuerde que debe incluir para que lo encuentre setw() – user1603472

+1

@ user1603472 Sí, pero mi código no usa 'std :: setw'. –

+0

lo siento, mi mal, hice clic en el lugar equivocado, fue un comentario rápido para poner en – user1603472