for (const auto &nums : entry.phones) { //
if (!valid(nums)) {
badNums << " " << nums; //
} else
//
formatted << " " << format(nums);
}
if (badNums.str().empty()) //
os << entry.name << " " //
<< formatted.str() << endl; //
else //
cerr << "input error: " << entry.name
<< " invalid number(s) " << badNums.str() << endl;
}
В этой программе подразумевается, что есть две функции, valid() и format(), которые проверяют и переформатируют номера телефонов. Интересная часть программы — использование строковых потоков formatted и badNums. Для записи в эти объекты используется обычный оператор вывода (<<). Но они действительно "пишут" строковые манипуляторы. Они добавляют символы к строкам в строковых потоках formatted и badNums соответственно.
Упражнение 8.13. Перепишите программу номеров телефонов из этого раздела так, чтобы читать из именованного файла, а не из объекта cin.
Упражнение 8.14. Почему переменные entry и nums были объявлены как const auto &?
Резюме
Язык С++ использует библиотечные классы для обработки потоков ввода и вывода.
• Класс iostream отрабатывает ввод-вывод на консоль.
• Класс fstream отрабатывает ввод-вывод в именованным файл.
• Класс stringstream отрабатывает ввод-вывод в строки в оперативной памяти.
Классы fstream и stringstream связаны происхождением от класса iostream. Классы ввода происходят от класса istream, а классы вывода — от класса ostream. Таким образом, операции, которые могут быть выполнены с объектом класса istream, могут быть также выполнены с объектом класса ifstream или istringstream. Аналогично для классов вывода, происходящих от класса ostream.
Каждый объект ввода-вывода обладает набором флагов состояния, указывающих, возможен ли ввод-вывод через этот объект. Если произошла ошибка (например, встретился конец файла в потоке ввода), то состояние объекта окажется таково, что никакой дальнейший ввод невозможен, пока ошибка не будет исправлена. Библиотека предоставляет набор функций для установки и проверки этих состояний.
Термины
Классfstream. Файловый поток, обеспечивающий чтение и запись в тот же файл. По умолчанию объект класса ifstreams открывает файл одновременно в режимах in и out.
Классifstream. Файловый поток, читающий данные из файла. По умолчанию поток ifstream открывается в режиме in.
Классistringstream. Строковый поток, читающий данные из строки.
Классofstream. Файловый поток, записывающий данные в файл. По умолчанию поток ofstream открывается в режиме out.
Классostringstream. Строковый поток, записывающий данные в строку.
Классstringstream. Строковый поток, читающий и записывающий данные в строку.
Наследование (inheritance). Программное средство, позволяющее типу наследовать интерфейс другого типа. Классы ifstream и istringstream происходят от классов istream и ofstream, а класс ostringstream происходит от класса ostream. Более подробная информация о наследовании приведена в главе 15.
Режим файла (file mode). Флаги классов заголовка fstream, устанавливаемые при открытии файла и задающие способ его применения. Строковый поток (string stream). Потоковый объект, читающий или записывающий данные в строку. Кроме возможностей, присущих классу iostream, классы строковых потоков определяют перегруженную функцию str(). Вызов функции str() без аргументов возвращает строку, с которой связан объект строкового потока, а ее вызов со строковым аргументом свяжет строковый поток с копией этой строки.
Файловый поток (file stream). Потоковый объект этого класса позволяет читать и записывать данные в именованный файл. Кроме возможностей, присущих классу iostream, класс fstream обладает также функциями-членами open() и close(). Функция-член open() получает символьную строку в стиле С, которая содержит имя открываемого файла и необязательный аргумент, задающий режим. Функция-член close() закрывает файл, с которым связан поток. Ее следует вызвать прежде, чем может быть открыт другой файл.