|
Программирование >> Разработка устойчивых систем
ществует функция narrow(), которая при необходимости преобразует символ в char. Функция widen О позволяет написать обобщенную версию представленного ранее манипулятора nl: tempiate<class charT. class traits> basic ostream<charT.traits>& nl(basic ostream<charT.traits>& os) { return OS charT(os.widen(\n)): Локальный контекст Вероятно, самым заметным различием в стандартах вывода числовых данных, принятых в разных странах, является выбор разделителя между целой и дробной частями вещественных чисел. В США таким разделителем является точка, а во многих странах мира - запятая. Было бы крайне неудобно вручную форматировать данные для разных национальных стандартов. Как и прежде, проблема решается созданием абстракции, которая нивелирует эти различия с точки зрения пользователя. Такая абстракция называется ло :йльиьш контекстом. С каждым потоком связывается объект локального контекста, параметрами которого поток руководствуется для отображения данных в конкретной культурной среде. Локальный контекст управляет несколькими категориями данных, отображение которых определяется национальными стандартами. collate Поддержка сравнения строк по разным схемам сортировки. ctype Абстракция классификации символов и средств преобразования, определяемых в файле <cctype>. monetary Поддержка разных форматов вывода денежных величин. numeri с Поддержка разных форматов вывода вещественных чисел, включая разделитель целой и дробной части и разделитель групп разрядов. time Поддержка разных международных форматов вывода даты и времени. messages Поддержка контекстно-зависимых каталогов сообщений (например, сообщений об ошибках на разных языках). Следующая программа демонстрирует простейшие операции с локальным контекстом: : С04:Local е.Срр {-g++}{-bor}{-edg) (RunByHand) Эффект от использования локальных контекстов #1nclude <1ostream> #1nclude <locale> using namespace std; int mainO ( locale def; cout def. name О endl: locale current = cout.getlocO: cout current.nameO endl: float val = 1234.56: cout val endl: Переключение на французский локальный контекст cout.1mbue(1ocalе( french )): current = cout.getlocO: cout current.nameO endl: cout val endl: cout Enter the literal 7890.12: : cin.imbue(cout.getloc()): cin val: cout val endl: cout.imbue(def): cout val endl: ) III:- A вот как выглядит результат: 1234.56 French France.l252 1234.56 Enter the literal 7890.12: 7890.12 7890,12 7890.12 По умолчанию используется локальный контекст С , хорошо знакомый программистам С и С++ (английский язык, американские стандарты). Все потоки изначально настраиваются на локальный контекст С . Функция imbue() потокового класса переключает локальный контекст потока. Обратите внимание: в результатах выводится полное название французского локального контекста по стандарту IOS (то есть французский язык, используемый во Франции, в отличие от французского, используемого в другой стране). Этот пример показывает, что во французском локальном контексте целая часть вешественного числа отделяется от дробной части запятой, а не точкой. Чтобы ввод данных также осуществлялся по правилам этого локального контекста, следует переключить на него cin. Каждая категория локального контекста делится на фацеты - классы, в которых инкапсулируется функциональность данной категории. Например, в категорию time входят фацеты time put и time get, содержащие функции соответственно для ввода и вывода даты/времени. Категория monetary содержит фацеты money get, money put и moneypunct (последний определяет знак денежной единицы). Следующая программа демонстрирует использование фацета moneypunct (фацет time требует нетривиальных операций с итераторами, выходящих за рамки темы этой главы). : С04:Facets.срр {-bor}{-g++}{-mwcc){-edg) #include <iostream> linclude <locale> linclude <string> using namespace std: int mainO { Упражнения 1. Откройте файл, создав объект ifstream. Создайте объект ostringstream, загрузите в него все содержимое файла функцией rdbuf(). Извлеките копию строки из буфера и преобразуйте все символы к верхнему регистру стандартным макросом toupper() языка С, определенным в файле <cctype>. Запишите результат в новый файл. 2. Создайте программу, которая открывает файл (первый аргумент в командной строке) и ищет в нем любое слово из заданного набора (остальные аргументы командной строки). Читайте входные данные по строкам и записывайте пронумерованные строки, в которых будут найдены совпадения, в новый файл. 3. Напишите программу, которая включает уведомление об авторском праве в начало каждого файла с исходным кодом программы, переданного в аргументах командной строки программы. Один из примеров - библиотека Abridged фирмы Dinkumware (htpp: \vww.dinkumware.com). Из библиотеки исключена поддержка локальных контекстов, а поддержка исключении является необязательной. Переключение на французский локальный контекст locale locCfrench ): cout.imbuedoc); string currency = use facet<moneypunct<char> >(loc).curr symbol (): char point = use facet<moneypunct<char> >(loc).decimal point(); cout I made currency 12.34 today! endl; } /:- В выходных данных отображаются французский символ денежной единицы и разделитель: I made С12.34 today! Вы также можете определять собственные фацеты для конструирования нестандартных локальных контекстов. Учтите, что применение локальных контекстов связано с существенными затратами. Некоторые разработчики библиотек выпускают диалекты стандартной библиотеки С++ для сред с ограниченными ресурсами. Итоги Данная глава достаточно подробно знакомит читателя с библиотекой потоков ввода-вывода. Вполне вероятно, этого материала будет достаточно для создания собственных программ, использующих потоки. Некоторые дополнительные возможности потоков требуются нечасто, и поэтому здесь не рассматриваются. Вы можете изучить их самостоятельно. Для этого достаточно просмотреть заголовочные файлы библиотеки потоков ввода-вывода, прочитать документацию компилятора или специализированные книги по этой теме.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |