Бьерн Страуструп. Язык программирования С++. Специальное издание (2011) (1004033), страница 161
Текст из файла (страница 161)
Если у источника нет символа для ввода, поток устанавливается в состояние ео)'Я2!.3.3), и если при этом исключение не генерируется, то возвращается гга!мз гуре!!еа!() . После возврата символа функцией и17ои() (но не функцией ииИег17ои ц ) дргг() инкрементируется. Помните, что в типичном случае в вашей системе буферов больше, чем их имеется в потоках юз» еат, так что могут иметь место задержки даже в случае использования небуферизованных потоков ввода/вывода. Функция озег77о)нО вызывается для передачи символов на реальное устройство по заполнении буфера. Вызов онег77оп (с) выводит содержимое буфера плюс символ с. Если вывод на устройство невозможен, поток устанавливается в состояние еоу' 521.3.3), и если при этом исключение не генерируется, то возвращается в а!т гуре:: ео)() . Функция зйонегапус ( ) — «з))озн 'позн шапу с))атас(егз» (показать, как много символов) — довольно странная функция, призванная помочь пользователю справиться о состоянии машинной системы ввода.
Она возвращает оценочное число символов, которые могут быть введены путем, например, сброса буферов операционной системы, а не ожиданием ввода с диска. Вызов зйоитаиус() возвращает -1 в случае, когда нельзя обещать ввода даже одного символа до возможной встречи с концом файла. Это очень низкоуровневая функция, сильно зависящая от реализации. Не пытайтесь ее испольэовать, не ознакомившись детально с документацией по вашей системе и не проведя некоторое количество экспериментов. По умолчанию, потоки используют глобально установленные характеристики локализации(интернационализации) (й217).
ВызовыриЬииЬие(!ос) или йиЬие(!ос) установят локализацию потоков с помощью объекта 1ос. 764 Глава 21. Потоки Для конкретного вида потока з<геатЬиу наследуется от Ьаяк з<геатЬаа. Он предоставляет конструкторы и функции инициализации, привязывающие з<геатбиУ к конкретному источнику символов или устройству их ввода, и замещает виртуальные функции, определяющие стратегию буферизации. Например; <етр<а<е<с1аяя Сй, с<от Тг = сйаг <гайз<Сй» с1ат Ьазк ЯебиУ'< риик Ьаз(с ялеатбиГ<СЬ, Тг> ( риЬ|с: Ьая!с !<!ебиХ() < пг<иа! -Ьаз(с <<!оба'() < Ьоо< <я орел() сопя« Ьая!с беби~* орел (соля< сйаг* р, 1оя Ьазе:: орелто«е то«е); Ьаз(с <<1ебиу> с<лис(); рго<ес<е<1 < Ыг<иа1 <и< яйо<гталус () < и!г<иа! ш« уре ил<<с<7!о<г() < г!г<иа1 ш« уре ит!о<я(); и!г<иа! йц <уре рбасйуа<1 (<л« уре с = Тг:: сои'( ) ) и!пиа! <п« уре иге<7!о<г (<т <уре с = Тг:: еоГ( ) ) < и!пиа< Ьаис я<геатбиу<СЬ, Тг>* яе<биу(Сй* р, я<гаити!зе и) < я<с<па! роз <уре зеейоЯ (оЯ' <уре о<)г, юяЬаяе:: яееИ<г <гау, юя базе::орепто<<с т = <оя Ьазе::ш) 1оя Ьаяе::ош) г(г<иа! роя <уре зеейроз (роз <уре р, <оя базе::орепто<те т = <оз Ьаие::<п) 1оз Ьазе::оил и<с<па! 1п< зупс () < г!г<иа1 гой! <тЬие (сопз< 1оса<еа 1ос) < Функции для манипуляции буферами и др.
наследуются без каких-либо изменений от Ьаз!с за еатбиу. Только функции, влияющие на инициализацию и стратегию буферизации должны определяться отдельно. Как обычно, с помощью операторов <уре<1еу предоставляются наиболее распространенные и очевидные типы: гуре«е/боя<с я<геатби/<сйаг> я<геатби7< <ура<<ау боя<с я<г(лябзу<сйаг> я<гшдбиГ< <уре<<еу Ьазк ЯебиГ<сйаг> у<1еби!< <уре«е/базк я<геатбиу<псйаг <> <гз<геатбир< <урез<с!' Ьаз(с з<плабиГ<ггсйаг <> <гз<г(пябиу'; <уре<!е!' боя<с Яебиу<псйаг <> пу<!еби<; 21.7. Локализация (интернационализация) Класс !оса!е отвечает за локализацию национально зависимых характеристик, таких как классификация символов на буквы, цифры и т.п.; он также имеет отношение к правилам сортировки строк и к внешнему виду представления числовых значений для ввода и вывода.
Чаще всего, класс 1оса!е используется в потоковой библиотеке ввода/вывода неявным образом, обеспечивая стандартные соглашения 2) .7 Локализация (интернационализация) 765 для некоторой группы естественных языков (в первую очередь — английского языка). Однако изменяя 1оса1е для потока, программист может «взять на себя» управление вопросами интернационализации/локализации программного обеспечения, обеспечив выполнение специфических языковых правил. Класс 1оса1е определен в пространстве имен мс( и представлен в заголовочном файле <!оса1е> (йО.2): 77 полное обьявление слс в з(Р.2 !оса(е (сот! 1оса1еь) Мгою() ! 77 копировать локализацию сонм !оса!ез орега!ог= (сопл! !оса!еа) Мгою () ! 7 копировать локализацию монс 1оса1е а(оба! (сопл! 1оса1ез); 77 установить глобальную локализацию з!апс сот11оса1еь с!азз1с(); 77 получить локализацию языка С )! В простейшем случае класс 1оса1е используется для того, чтобы переключить языковые правила с текущих на иные.
Например; ио1а !'( ) ( за!:: !оса(е 1ос ( " РОЯ1Х" ) ! 77 стандартная локализация для РОЯХ ст. ипЬие (!ос) ! 7 пусть с!п использует !ос 77 ... с(п. стЬие (зза:: 1оса1е () ) ! 77 возвращаем для с!и умолчательную глобаль. локализацию ) Функция ззпЬие() является членом класса Ьаз1с юз (в21.7.1). Как показано в примере, некоторые наиболее распространенные правила интернационализации имеют зарезервированные строковые имена. Они, как правило, коррелируют в предпочтениях с языком С. Можно зафиксировать параметры локализации так, чтобы они по умолчанию использовались всеми создаваемыми потоками: 77 текущая умолчательная глоболь. лакал-я ио(а я(сот! 1оса1еь 1ос = 1оса1е () ) ( !оса!в о!й я1оЬа1 = 1оса)е::я!оба! (1ос) ! 77 теперь !ос будет умолчательной лакал-ией 7...
) Установка глобальных языковых характеристик не влияет на существующие потоки. В частности, это не оказывает влияния на с!и, сои! и т.д. Для влияния на эти потоки к ним нужно применить функцию 1пзЬие () . Это изменяет многие детали их поведения. Можно использовать члены класса 1оса1е напрямую, можно определять новые объекты локализации, можно дополнять их новыми особенностями. Например, их можно применить для изменения обозначения денежных единиц при вводе/выводе, формата дат и т.п. 521.10[25)), а также для преобразования кодировок. Концеп- с1азз 1оса1е ( 77 ...
!оса!в() Мгою(); ехр11с11 1оса1е (сот! сйаг* пате); Ьаз(с з!ггпя<сдаг> пате () сот!; 77 копия текущей глобальной локализации 7 создать локализацию по кивни С-локализации 77 получить имя данной локализации Глава 2). Потоки гбб ция объектов локализации, классы 1оса1е и/асег, а также стандартные объекты этих классов рассматриваются в приложении Р. Локализация в стиле языка С представлена в заголовочных файлах <с!оса(е> и <1оса1е.
Й>. 21.7.1. Функции обратного вызова дпя потоков Иногда требуется что-то добавить к состоянию потока. Например, кому-то может потребоваться, чтобы поток «знал», в каком виде выводить числа типа сотр1ех — в полярных или декартовых координатах. Класс Ыз Ьат предоставляет функцию хавас() для выделения памяти под простую информацию о состоянии потока. Возврат функции хаИос() идентифицирует местоположение, к которому можно обратиться с помошью функций 1иогИ() и рнюгИ(): с1ат 1оз Ьале ( риЬИс: И.
-гоз Ьазе(); !оса!е йиЬие (сопл! !оса(еь (ос); Иустановить локолиз-ю (вернуть старую) (Зь).2.3) !оса(е веков () сопи; И получить локализацию иабс 1пг хаИос ( ); УУ получить целое и указатель (инициализированы 0) !оиеа !той ((п!!); УУ доступ к целоиу !иогд(И коЫ*а рюоп$(!п! !); И доступ к указателю рыопИИ У обратные вызовы: епит екепз (егазе еиепг, )тЬие е»епг, сору~т< еиеп!) ! И типы событий (урезе/'иоЫ (*екеп! саИЬасй) (е»епг, !ол Ьазеа, (н( 1); иоЫ гее(з!ег саИЬасй(еиеп! саИЬасй/, Ыг!); УУирикрепить|крнюп1(1) Иногда разработчику реализации или пользователю нужно знать об изменении состояния потока.
Функция гея1з!ег саИЬасл() регистрирует функцию, которая будет вызвана при наступлении»ее события», В итоге, при вызовах йлЬле(), соруйлг() или -1ов Ьаве () будут вызваны функции, зарегистрированные для событий 1тЬие евелг, соруйлг евелг или егаве егелг, соответственно. При изменении состояния зарегистрированные функции вызываются с аргументом риогИ(!), где ! соответствует их гел(хгег саИЬас1с() . Эти механизмы хранения и обратного вызова довольно запутанные. Применяйте их лишь при крайней необходимости в расширении возможностей форматирования нижнего уровня.
21.8. Ввод/вывод языка С Поскольку код С+-ь и код С часто перемешиваются в рамках одного проекта, потоки ввода/вывода С++ сосушествуют с семейством функций рг1лбг() языка С. Функции ввода/вывода в стиле С представлены в заголовочных файлах <савва> и <з!И(о. Ь>. Поскольку С-функции можно вызывать из С++-кода, некоторые про- 2).8 Ввод/выводязыка С 767 граммисты любят использовать более привычные им функции ввода/вывода языка С.
Даже если вы сами предпочитаете работать с потоковым вводом/выводом, вы все равно когда-нибудь столкнетесь со вводом/выводом в стиле языка С. Ввод/вывод языков С и С++ может быть смешанным — вызов хупс и!1Ь же!!о() до применения в программе операций потокового ввода/вывода гарантирует, что операции ввода/вывода языков С и С++ будут использовать общие буферы. В то же время, вызов хупс в!1Ь хпйо ~а!хе) в том же контексте предотвращает совместное использование буферов и может улучшить производительность ввода/вывода: с1ат !ое Ьаге ( У... ага!!с Ьоо! еупс в!(Ь еа!!о (Ьоо! еупс = (гие) ! )! Главным преимушеством потоковых функций вывода перед функцией рг!пр() из стандартной библиотеки языка С состоит в том, что они безопасны по отношению к разным типам, и что вывод с их помощью встроенных и пользовательских типов выполняется в едином стиле.
Основные функции языка С для вывода т! рг!п(1" (соле! сьаг* /огта!... ) ! Упишет в гЫоис !и!Я>к!пф'(г1сЕ*, соле! сдпг" /оста!... ) ! гу пишет е "ф!е" !гнои(, гМегг) !п! ерппг/(сдпг* р, сова! сьаг* /оста!... ) ! кУ пишет о р/О/ ... выполняют форматированный вывод произвольной последовательности аргументов под управлением форматирующей строки /акта!. Форматирующая строка содержит два вида элементов — обычные подлежащие выводу символы и форматирующие спецификаторы, каждый из которых вызывает выполнение преобразования и вывод очередного аргумента. Форматирующие спецификаторы начинаются символом Ь. Например: рк!пг/("!деке веке Ы тетЬеге ргеееп!.
", по о/ тетЬеке) Здесь Иозначает, что аргумент по о/' тетЬекадолжен трактоваться как !лги выводиться в виде соответствующей последовательности десятичных цифр. Если, например, по о/' тетЬег~=127, то на выходе получим: гдеге веге 127 тетЬегз ргеееп!. Набор спецификаций преобразований довольно велик и обеспечивает высокую степень гибкости. После знака а может присутствовать следующее: — необязательный знак минус, который специфицирует выравнивание влево преобразованного значения внутри поля; е необязательный знак плюс, который требует, чтобы значения знаковых типов выводились с лидирующими к или —; О необязательный пуль, который приводит к тому, что выводимое числовое значение дополняется лидирующими нулями.