C++ 3d.Комментарии


Манипуляторы, определяемые пользователем


Коль скоро с эффективностью потоков ввода-вывода мы уже разобрались, следует поговорить об удобстве. К сожалению, для сколько-нибудь сложного форматирования предоставляемые потоками средства не предназначены. Не в том смысле, что средств нет, а в том, что они чрезвычайно неудобны и легко выводят из себя привыкшего к элегантному формату ...printf() программиста. Не верите? Давайте попробуем вывести обыкновенную дату в формате dd.mm.yyyy: int day= 31, mon= 1, year=1974;

printf("%02d.%02d.%d\n", day, mon, year); // 31.01.1974

cout<<setfill('0')<<setw(2)<<day<<'.'<<setw(2)<<mon<<setfill(' ')<<'.' <<year<<"\n"; // тоже 31.01.1974

Думаю, что комментарии излишни.

За что же не любят потоки C и чем потоки C++ могут быть удобнее? У потоков C++ есть только одно существенное достоинство -- типобезопасность. Т.к. потоки C++ все же нужно использовать, я написал специальный манипулятор, который, оставаясь типобезопасным, позволяет использовать формат ...printf(). Он не вызывает существенных накладных расходов и с его помощью приведенный выше пример будет выглядеть следующим образом: cout<<c_form(day,"02")<<'.'<<c_form(mon,"02")<<'.'<<year<<'\n';

Вот исходный код заголовочного файла: #include <ostream>

/** личное пространство имен функции c_form, содержащее детали реализации */ namespace c_form_private {

typedef std::ios_base::fmtflags fmtflags; typedef std::ostream ostream; typedef std::ios_base ios;

/** * Вспомогательный класс для осуществления форматирования. */ class Formatter { /** флаги для установки */ fmtflags newFlags; /** ширина */ int width; /** точность */ int prec; /** символ-заполнитель */ char fill; /** сохраняемые флаги */ fmtflags oldFlags;

public: /** * Создает объект, использующий переданное форматирование. */ Formatter(const char* form, int arg1, int arg2);

/** * Устанавливает новое форматирование для переданного потока, сохраняя * старое. */ void setFormatting(ostream& os);




- Начало -  - Назад -  - Вперед -



Книжный магазин