Как удалить избыточность в форматированном потоке

У меня есть следующий рабочий код, который создает форматированный вывод с использованием ofstream, однако я чувствую, что все повторяющиеся спецификаторы формата затрудняют чтение. Есть ли способ установить точность, ширину и выравнивание на постоянной основе для данного потока, что бы хорошо все очистить?

#include <fstream>
#include <iomanip> 

ofstream myfile;
myfile.open(Output.c_str(), ios::trunc);
for (int i = 0; i < iLen; i++) {
   myfile <<std::fixed << std::setw( iWidth ) << std::setprecision( iDecimals )<< std::right << pDist[i]  << "   "
      <<std::fixed << std::setw( iWidth ) << std::setprecision( iDecimals )<< std::right << pRes[i]   << "   "
      <<std::fixed << std::setw( iWidth ) << std::setprecision( iDecimals )<< std::right << pPhase[i] << "\n";
}
myfile.close();

person marcp    schedule 28.10.2014    source источник
comment
Вы пытались просто удалить повторяющиеся спецификаторы формата? Большинство спецификаторов формата сохраняются до тех пор, пока они не будут снова явно изменены.   -  person Code-Apprentice    schedule 28.10.2014
comment
std::fixed, std::setprecision и std::right являются постоянными. Единственный, который вам нужен каждый раз, это setw.   -  person Calvin Scherle    schedule 28.10.2014
comment
@CalvinScherle прав. Я попытался удалить спецификаторы, как было предложено Code-Apprentice, но это не сработало, потому что я удалял их все. Спасибо, переполнение стека!   -  person marcp    schedule 28.10.2014


Ответы (2)


std::fixed, std::setprecision и std::right все "постоянные". Они устанавливают постоянные флаги для объекта потока.

Единственное, что нужно ставить каждый раз, это setw, который (как я понимаю) не устанавливает флаг на поток object, а просто добавляет некоторое количество пробелов, изменяя сам поток. Но он оставляет поток в покое.

Это похоже на endl, который работает с потоком, но не трогает фактический объект потока.

Этот ответ от @LokiAstari на аналогичный вопрос подробно описывает, какие спецификаторы, по их словам, являются "липкими" (и почему) .

EDIT: устранены различия между объектом потока и фактическим потоком.

person Calvin Scherle    schedule 28.10.2014

Единственный манипулятор, о котором вам нужно беспокоиться, это std::setw, так как ширина возвращаться к нулю всякий раз, когда вызывается operator<<. Перед циклом вы можете установить свои «постоянные» флаги ios:

myfile << std::fixed << std::setprecision(iDecimals) << std::right;
for (int i = 0; i < iLen; i++) {
   myfile << std::setw( iWidth ) << pDist[i] << "   "
      << std::setw( iWidth ) << pRes[i] << "   "
      << std::setw( iWidth ) << pPhase[i] << "\n";
}

Если вы хотите снять эти флаги за один раз, вы можете использовать:

std::cout.copyfmt(std::ios(NULL));

Как указано в этом ответе.

person Community    schedule 28.10.2014