2012-06-27 5 views
12

В коде C++ у меня есть матрица двойных переменных, которую я распечатываю. Однако, поскольку все они имеют разное количество цифр, выходной формат уничтожается. Одно из решений - сделать cout.precision(5), но я хочу, чтобы разные столбцы отличались точностью. Кроме того, поскольку в некоторых случаях есть отрицательные значения, наличие знака - также вызывает проблемы. Как обойти это и создать правильно отформатированный вывод?Форматирование вывода в C++

ответ

10

Off верхней части моей головы, вы можете использовать setw (целое), чтобы указать ширину вывода.

так:

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 
+0

только FYI: при выполнении std :: setw (x) убедитесь, что x больше вашей десятичной точности. – solti

4

manipulators.

Из образца 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'; 
} 

Выход:

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

Посмотрите на поток 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 
0

Существует способ использования манипуляторов ввода-вывода, но я нахожу его громоздким. Я бы просто написать такую ​​функцию:

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

Ключ, как уже говорили другие, использовать манипуляторы. Что они отрицают, так это то, что вы обычно используете манипуляторы, которые вы пишете самостоятельно. 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... 

В целом, за исключением простейших программ, вы, вероятно, не должны быть , используя стандарт манипуляторы, а скорее настраиваемые манипуляторы на основе вашего приложения; например temperature и pressure если это вещь, с которой вы имеете дело. Таким образом, в коде ясно, что вы форматируете , и если клиент вдруг запросит еще одну цифру в давлении, вы точно знаете, где внести изменения.

+0

Помните, что вам нужно включить , чтобы найти его. ( – user1603472

+1

@ user1603472 Да, но мой код не использует 'std :: setw'. –

+0

извините, мой плохой, я нажал не туда, был быстрый комментарий – user1603472

Смежные вопросы