Б. Страуструп - Язык программирования С++. Специальное издание, 3-изд. Бином. 2004 (1160791), страница 156
Текст из файла (страница 156)
Стандартные манипуляторы ввода/вывода Стандартная библиотека предоставляет манипуляторы, относящиеся к различным состояниям формата и изменению состояний. Стандартные манипуляторы определены в пространстве имен з1с(. Манипуляторы, использующие юз Ьазе, представлены в <сок>. Манипуляторы, использующие !к!сват и оз1геат, представлены в <Ек1геат> и <оз1геат> соответственно, и, кроме того, в <юк1геат>. Остальные стандартныс манипуляторы представлены в <ютапср>, сок Ьазс&Ьоо(аЕрда(!аз Ьазей); //символьнаепрсдставление1гиеи/а)хе Епривводеивыводе) Еаз Ьаксй поЬооЕаЕраа (!оз Ьизейз); //з1глспяе1/(!оз Ьаяенбоо(а!р!ш) Еак ЬазсйзЬахиЬазе (юк Ьазе&) //включаст вывод О перед восьмеричными и Ух //перед шестнадцатеричными чйслами соз ЬакейаокпоюЬазе(Еок Ьазей); //кише1/(!оз Ьаяенз!союбаяе) 21.4.
Форматирование //заполнители перед зничением // десяпгичная система счисления, у" 2!.4.2 // шестнадцатеричная система счисления // восьмеричная система счисления //формат ЙЬЫЫй числа //с плавающейточкой Ц 2!.4.З) // научный формат й йдййр Ы 1оя Ьаяей/гхес!(юз болей) юз Ьаяейяс!еп1с)сс(!оя Ьаяей); гетр1а!е<с!аяв СЛ, с!вяз Тг> Ьаз!с оз1геат<СЬ, Тг>й епс!1(Ьаягс ояггеат<СЬ, Тг>й), //запись '~п' и очистка 1етр!а1е<с!акк СЬ, с1аяз Тг> боя!с омгеат<СЬ, Тг>й епг)в (базк ояггеат СЬ, Тг>йг //запись и~ф 1етр1аге<с1аяя СЬ, с!азз Тг> бая!с озггеат<СБ, Тг>йЯияб (Ьав!с оя1геат<СЬ, Тг>й) //очистка буфера потока 1етр!а1е<с!аяя СЬ, с1азя Тг> Ьая!с !я1геат<СЙ, Тг>й юз (Ьая(с овг еат<СЬ, Тг>й) //прочеапьи проигнорировать //все символы-разделители ятапгр геяе11оя/! ауя (юз базе;:~тЯаукЯ; ктап1р ве11оя/(ауя (юя баке.ХтЦ1аузЯ; ктатр яегЬаве (т1 Ь); зтап!р веЯ!! (он с); зтап!р яе1ргесгягоп1((п1п); ятапгр яе1ш (т1 и), Например, сои!«!234«','«Ьех«!284«','«ос1«!274«епс!1; выведет 1224, 4с!2, 2822, а сои1 « ' (' «зеив (4) «зе1ЯИ ('№') « '(' «12 «') (' «12 «') ччп, выведет (№№12) (12).
При использовании манипуляторов без аргументов не ставьте скобок. При использовании стандартных манипуляторов с аргументами, не забудьте включить №!пс1иг!е<1отап1р>. Например: №(пс1ийе<!ов1геит> азгпу патеврасе вИ 1п1 тата () ( 21.4.6.3. Манипуляторы, определяемые пользователем Программист может добавлять собственные манипуляторы, написанные в том же стиле, что и стандартные. Здесь я представляю дополнительный стиль, который, мне кажется, может пригодиться для форматирования чисел с плавающей точкой. !оз Ьазейпубг(!оя базей); 1оя болей с!ес(!ов Ь ней).
!оя Ьаяей бек(!оя баяей); гок Ьаяейос1 (!оя Ьазей); ия!пд патевраве зЫ; сои! «зе1ргесмюп (4) «зс)ел1фс () «1.41421 «епд1; 0сбросфлагов !З 2!.4) // установка флагов !у 2!.4) // вывод целых чисел в системе //счисления с основанием б !у 2!.4 2) //сделать с символом заполнения (у' 21.4 4) //и цифр бб 2!.4.3, 21.4.б.!) // в следую!цт вводе — и сичв алов !у' 2)лб4) // ошибка: ве1рггаяоп не определена (забьыи чотитр>) //ошибка: ов1геат< овйеатй 1неумеспгные скобки) Глава 21, Потоки 702 Гогт зс!8 = уеп4; зс!В.зс!еп1(/)с ()ргес!з!ол (8); // научный форльат, точность 8 сои1 «а! « ' ' «Ве п4 (д) « ' ' «зс(В (д) « ' ' «с! «ьчп'; При вызовеЯ1234.5б789) выведется 12345 7 ! 235 !2345б78 уе+ 03 123457 Отметим, что использование Рост не влияет на состояние потока, так что последний вывод числа ь( имеет тот же формат по умолчанию, что и первый. Вот упрощенная реализация: с!вяз Воипй /огт, //Гост плюс значение с1азз Гогт ( 1ггепс( озггеатй орега1огч < (оз1геатй, сопз1 Воипй Гостй) !л1ргс; // точность !п1 из(1; О ширина поля, 0 означает столько цифр, сколько нужно !л1/т1, //универсальныи, научныйилификсированныйформаты Ц 2!л63) риЫ(с; екр!!с!1 Гост (ш1 р=б): р ге (р) Хт1=0; и01= 0, // по умолчанию точность б //универсальныйформат Ц 2!.4.3) //столько иифр, сколько понадобится Воипй /огт орега1ог () (йоиЫе с!) соля!; //создание связаннойфорлы для *1Ии и д Гогт й зс!епг(/!с () (/т1 = !оз Ьазесзс!еп15с; ге1игп *1Ыз; ) Гогтй/иес!() (/т1= !оз Ьазе: ркес(; ге!игл '1Аи; ) Гог тй делега! () (/т1 = 0; ге(игп *183з; ) Гогтй иррегсазе (); Го гт й !оиегсазе (); Гогтй ргес!я!оп (шгр) ( ргс = р, ге!игл *Ми; ) Гогтй и!016 (!пги) (иЯ= и, ге!игл 'йи;) //прил~еняется ко вселг типам ГогтйЯ!! (сааг); ч Гогт й р!ия (Ьо о! 6 = ггие); //явный плюс Гогтй 1га!Илу еегоя (Ьоо! Ь = 1гие); //вывод незначаи(икнулеи 0- Введенная точность сохраняется для всех операций вывода, но операция ш!с(1/ь () применяется только к ближайшей операции численного вывода, Мне же хотелось бы сделать нечто такое, что позволит просто выводить число с плавающей точкой в желаемом формате, не затрагивая последующих операций вывода в поток.
Основная идея заключается в определении некоторого класса, который бы представлял форматы, другого, который бы представлял формат и форматируемое значение, и еьце одного оператора «, который в соответствии с форматом выводил бы зто значение в оз1геат. Например: Гоге Вепу (4); //универсальныйформат, точность 4 оо!с(,/ (с(оиЫе д) 21.5. Файловые и строковые потоки йгис1 Воипй аост ( сопз1гогте Д йоиЫе оа1; Воипй /огт (сон я1 гогтй~Я йои Ые о) .У(//), оа1 (о) () Воипй /огт Гогтсорега1ог () сопя!(йоиЫе ф ( ге1игп Воипй /огт (*1Ыя, сб; ) ояггеатс орега1ог«(оз1геитй оя, сопя! Воиай /огтй Ь/) ( // сп7роковые потоки описань~ в ф' 2!.53 оя1г!пдяггеат я; я,ргесийоп (ЬЦргс) я.зе1/(ЬЯ//т1, !оя Ьазе:Яоа()!е!й); я «Ь1'оа1; ге1игп оз «зв1г (); // составление строки в я // вывод я в оя Написание менее примитивной реализации оператора «я оставляю в качестве упражнения (э 21.10(21)).
Классы Гогт и Воняй аост легко расширяются для форматирования целых чисел, строк и т. д. (см. 0 21.10[20)). Отметим, что этн объявления превращают операторы «и () в тсрнарный оператор; сои!«яс14 (й), прежде чем производить действительные вычисления, собирает оз1геат, формат и значение в единую функцию. 21.5.
файловые и строковые потоки Когда программа на С++ начинает выполняться, можно пользоваться сои1, сегг, с!од, с!и и их эквивалентами для расширенных символов Я 21.2 1). Эти потоки доступны по умолча!пно, а их связь с устройствами ввода/вывода или файлами определяется «системой». Кроме того вы можете создать свои собственные потоки. В этом случае вы должны указать, к чему их следует прикрепить. Доволъно часто поток прикрепляют к файлу илн к строке я1г!пи, и поэтому такие действия поддерживаются стандартной библиотекой. Здесь представлена иерархия классов стандартных потоков: !оз Ьазе газ<> !я1геат<> ' озггеат<> !я!г!пня геат<> !Ягеат<> !оз!геат<> о/я! еат<> /ятгеат<> яптпиз1геат<> оягг!пиз геат<> Идея заключается в том, ьтобы Гост содержал всю информацию, нужную для форматирования одного элемента данных. Выбор по умолчанию должен быть полезен для многих применений, а различные функции-члены можно использовать для задания отдельных аспектов форматирования.
Оператор () используется для связывания значения с форматом, который используется для его вывода. Тогда Воин!! ~огт может может быть выведена в данный поток соответствуюгдей функцией «: Глава 21. Потоки 704 Классы с суффиксом <> являются шаблонами, параметры которых имеют символьный тип; их имена начинаются с Ьая(с . Пунктирная линия означает виртуальные базовые классы [б 15.2А). Файлы и строки — это примеры контейнеров, из которых можно считывать и в которые можно записывать.
Следовательно, вы можете завести поток, поддерживающий как оператор «, так и». Такой поток называется !оя1геаяп, он определен в пространстве имен зЫ и представлен в <1оз1геат>: 1етр1аге<с1азз СЛ, с1азз Тг = сбаг 1гайз<СЬ» с(азз баяне !озггеат; рибйс Ьаз!с изгеат<СЬ, Тг>, риб!1с баз!с озггеат<СА, Тг> ( рибй: ехр!!с11 Ьаз!с (оз1геат (боя!с зггеатбиХ Сб, Тг>' зЬ); о!ггиа1-Ьаз!с юз1геат (); 1урейе1'Ьаз!с юяггеат<сбаг> юз1геат; 1урепе7'Ьаз!с юзб.сит<тобах 1> т!озггеат; Управление чтением и записью в тз1геат осуществляется через две операции над буфером з1геатби!" потока !аз!гент — «записать в буфер» и <прочесть из буфера>, 21.5.1.