Д. Стефенс - C++. Сборник рецептов
- Название:C++. Сборник рецептов
- Автор:
- Жанр:
- Издательство:КУДИЦ-ПРЕСС
- Год:2007
- Город:Москва
- ISBN:5-91136-030-6
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Д. Стефенс - C++. Сборник рецептов краткое содержание
Данная книга написана экспертами по C++ и содержит готовые рецепты решения каждодневных задач для программистов на С++. Один из авторов является создателем библиотеки Boost Iostreams и нескольких других библиотек C++ с открытым исходным кодом. В книге затрагивается множество тем, вот лишь некоторые из них: работа с датой и временем; потоковый ввод/вывод; обработка исключений; работа с классами и объектами; сборка приложений; синтаксический анализ XML-документов; программирование математических задач. Читатель сможет использовать готовые решения, а сэкономленное время и усилия направить на решение конкретных задач.
C++. Сборник рецептов - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
<< setw(width) << citystate << endl;
cout.flags(flags);
}
Вывод выглядит следующим образом.
Richard Stevens Tucson, AZ
Манипулятор — это функция, которая выполняет некоторую операцию над потоком. Применяемые к потоку манипуляторы задаются в операторе operator<<
. Формат потока (ввода и вывода) задается набором флагов и установочных параметров конечного базового класса потока, ios_base
. Манипуляторы обеспечивают удобный способ настройки этих флагов и установочных параметров без явного использования для этой цели функций setf
или flags
, которые громоздки и воспринимаются с трудом. Для форматирования потока вывода лучше всего использовать манипуляторы.
В примере 10.1 используется два манипулятора для вывода текста в две колонки. Манипулятор setw
задает размер поля, a left
обеспечивает выравнивание влево находящегося в поле значения (дополнением манипулятора left
, что неудивительно, является right
). Когда вы используете слово «поле», вы просто говорите, что хотите дополнить заполнителем выдаваемое в поле значение с одной или с другой стороны, чтобы только ваше значение выводилось в этом поле. Если, как в примере 10.1, вы выравниваете значение влево и затем задаете размер поля, следующее записываемое в поток значение будет начинаться с первой позиции этого поля. Если переданные в поток данные имеют недостаточный размер и не могут заполнить все пространство поля, то правая часть поля будет дополнена символом заполнителя потока, которым по умолчанию является одиночный пробел. Вы можете изменить символ заполнителя с помощью манипулятора setfill
.
myostr << setfill('.') << "foo";
Если помещаемое в поле значение превышает его размер, будет напечатано все значение и никаких дополнительных символов выводиться не будет.
Табл. 10.1 содержит краткое описание манипуляторов, работающих с любыми типами значений (текстом, числами с плавающей точкой, целыми числами и т.д.). Имеется ряд манипуляторов, которые применяются только при выводе чисел с плавающей точкой — они описываются в рецепте 10.2.
Табл. 10.1. Текстовые манипуляторы
Манипулятор | Описание | Пример вывода |
---|---|---|
left right |
Выровнять значения в текущем поле вправо или влево, заполняя незанятое пространство символом-заполнителем | Выравнивание влево apple banana cherry Выравнивание вправо (ширина поля 10) apple banana cherry |
setw(int n) |
Установить размер поля на n символов | См. предыдущий пример |
setfill(int с) |
Использовать символ с для заполнения незанятого пространства поля | cout << setfill('.') << setw(10) << right << "foo" Выдает: .......foo |
boolalpha noboolalpha |
Отобразить булевы значения в текущем локализованном представлении слов true и false , а не 1 и 0 |
cout << boolalpha << true Выдает: true |
endl |
Записать в поток символ новой строки (newline) и очистить буфер вывода | Нет |
ends |
Записать в поток null-символ ('\0') | Нет |
flush |
Очистить буфер вывода | Нет |
Некоторые представленные в табл. 10.1 (и в табл. 10.2 в следующем рецепте) манипуляторы переключают бинарные флаги потоков и в действительности реализуются как два манипулятора, которые включают и отключают флаг. Например, возьмем манипулятор boolalpha
. Если вы хотите, чтобы булевы значения отображались в соответствии с текущей локализацией (например, «true» и «false»), используйте манипулятор boolalpha
. Для отключения этого режима, чтобы вместо слов печатались 0 и 1, используйте манипулятор noboolalpha
(он используется по умолчанию).
Действие всех манипуляторов сохраняется до тех пор, пока оно не будет явно изменено, исключая манипулятор setw
. Из примера 10.1 видно, что он вызывается перед каждой записью, однако left
используется только один раз. Это объясняется тем, что ширина поля устанавливается в нуль после записи каждого значения в поток при помощи оператора operator<<
; чтобы обеспечить одинаковую ширину всех полей, мне пришлось каждый раз вызывать setw
.
Стандартные манипуляторы позволяют делать многое, но не все. Если у вас возникает потребность в написании собственного манипулятора, см. рецепт 10.2.
Как и все другие классы стандартной библиотеки, работающие с символами, манипуляторы работают с потоками узких или широких символов. Поэтому вы можете использовать их в шаблонах для написания утилит форматирования, обрабатывающих потоки символов любого вида. В примере 10.2 приводится шаблон класса TableFormatter
, который форматирует данные в колонки одинаковой ширины и выдает их в поток.
Пример 10.2. Параметрический класс для табличного представления данных
#include
#include
#include
#include
using namespace std;
// TableFormatter выдает в поток вывода символы типа T в форматированном
// виде.
template
class TableFormatter {
public:
TableFormatter(basic_ostream& os) : out_(os) {}
~TableFormatter() {out_ << flush;}
template
void writeTableRow(const vector& v, int width);
//...
private:
basic_ostream& out_;
};
template
typename valT> // ссылается на список параметров функции-члена
void TableFormatter::writeTableRow(const std::vector& v,
int width) {
ios_base::fmtflags flags = out_.flags();
out_.flush();
out_ << setprecision(2) << fixed; // Задать точность в случае применения
// чисел с плавающей точкой
for (vector::const_iterator p = v.begin(); p != v.end(); ++p)
out_ << setw(width) << left << *p; // Установить ширину поля, его
// выравнивание и записать элемент
out_ << endl; // Очистить буфер
out setf(flags); // Восстановить стандартное состояние флагов
}
int main() {
TableFormatter fmt(cout);
vector vs;
vs.push_back("Sunday");
vs.push_back("Monday");
vs.push_back("Tuesday");
fmt.writeTableRow(vs, 12);
fmt.writeTableRow(vs, 12);
fmt.writeTableRow(vs, 12);
vector vd;
vd.push_back(4.0);
vd.push_back(3.0);
vd.push_back(2.0);
vd.push_back(1.0);
fmt.writeTableRow(vd, 5);
}
Вывод представленной в примере 10.2 программы выглядит следующим образом.
Sunday Monday Tuesday
4.00 3.00 2.00 1.00
Таблица 10.1, рецепт 10.2.
10.2. Форматирование вывода чисел с плавающей точкой
Требуется выдать числа с плавающей точкой в удобном формате либо ради обеспечения необходимой точности (применяя нотацию, которая используется в науке, а не в виде числа с фиксированной точкой), либо просто выравнивая значения по десятичной точке для лучшего восприятия.
Читать дальшеИнтервал:
Закладка: