Бьерн Страуструп. Язык программирования С++. Специальное издание (2011) (1004033), страница 151
Текст из файла (страница 151)
Здесь рассматриваются средства записи встроенных и пользовательских типов в выходной поток. 821.3 Ввод; Здесь рассмотрены средства ввода символов, строк и других встро- енных и пользовательских типов данных. 82!.4 Форматирование: Часто на внешний вид вывода накладываются специ- альные требования. Например, значения типа !л! нужно выводить в десятич- ном виде, а указатели — в шестнадцатеричном; числа же с плавающей запятой часто требуется выводить с заданной степенью точности.
Обсуждается управ- ление форматированием и соответствующие приемы программирования. 821.5 Файлы и потоки: По умолчанию, каждая С++-программа может исполь- зовать стандартные потоки, такие как сои! (вывод), с!я (ввод) и сегг (поток ошибок). Чтобы использовались конкретные устройства и файлы, потоки должны к этим устройствам и файлам прикрепляться.
Описываются механиз- мы открытия и закрытия файлов, а также прикрепление потоков к файлам и строкам згг!яя. 821.6 Буферизация: Чтобы ввод/вывод был эффективным, нужно реализовать стратегию буферизации, удобную как для данных (читаемых или записывае- мых), так и для их источника/приемника. Описываются основные способы буферизации потоков. 821.7/7окализаиия: Объект !оса!е специфицирует внешний вид выводимых чи- сел, какие символы считать буквами и т.д.
Он инкапсулирует нюансы вво- да/вывода, зависящие от национальных (локальных) особенностей. Послед- ние используются системой ввода/вывода неявно и рассматриваются здесь очень кратко. $21.8 Ввод/вывод в стиле языка С: Обсуждается библиотечная функция языка С рг!яг/'() из заголовочного файла <згйо.й> и связь этой библиотеки с биб- лиотекой С++ из <!взггеаяг>. ввода ному Знание средств реализации потоковой библиотеки не обязательно для ее успешного использования. Кроме того, реализация различается от системы к системе. В то же время, реализация ввода/вывода — задача не только сложная, но и интересная.
реализация ввода/вывода содержит интересные решения, пригодные лля использования в иных сферах. Именно поэтому с технологиями, лежащими в основе реализации ввода/вывода, ознакомиться полезно. В данной главе потоковая система ввода/вывода изучается ровно в той степени, которая позволит вам оценить ее структуру, применять ее на практике для самых общеупотребительных случаев, а также позволит вам расширять ее для работы с новыми пользовательскими типами данных. Если же вы хотите сами написать стандартный поток, ввести новый вид потока или в деталях учесть нюансы, зависящие от национальных языков, вам придется ознакомиться со стандартом, хорошим системным справочником и примерами работающего кода в добавок к тем, что представлены в данной главе.
719 21.2. Вывод Ключевые компоненты системы потокового ввода/вывода показаны на рисунке: Пунктирная стрелка, идущая от Ьавгс ювггеат<>, означает, что Ьаяс юв<> является виртуальным базовым классом; сплошные стрелки соответствуют указателям. Классы, содержащие в имени угловые скобки, являются шаблонами, параметризуемыми символьным типом и содержащие национальные особенности представления символов. Концепция потоков и присущая ей стандартная система обозначений приложимы к широкому кругу задач. Потоки применяются при передаче объектов между компьютерами (В25.4.1), при шифровании потока сообщений (В21.10[22) ), для сжатия данных, для долговременного хранения объектов и для решения многих других задач.
Но в данной главе обсуждение ограничивается стандартным вводом/выводом, ориентированным на символы. Объявления классов потокового ввода/вывода и шаблонов (достаточные для обращения, но не для использования) и определения операторами )уроде/'стандартных типов представлены в заголовочном файле <ювйвд>. Этот заголовочный файл требуется в тех случаях, когда вы хотите включить лишь часть из всех средств ввода/вывода. 21.2. Вывод Однородный и безопасный подход как ко встроенным типам, так и к типам, определяемым пользователем, достигается за счет перегрузки функций вывода.
Например: рш(сегг, "х=") ) ~Усегг это поток вывода ошибок рив (се1т, х); риг(сегг, ' ~п' ); Тип аргумента определяет выбор конкретной функции. Это решение хорошо известно (в том числе и в других языках программирования), но оно слегка тяжеловесное в связи с назойливым повтором имени функции. Перегрузка операции « (поместить в поток) существенно улучшает запись операции вывода и позволяет программисту осуществлять вывод последовательности объектов в рамках единственного оператора языка С++.
Глава 2) Потоки сегг « "х= "«х« ' хп'; Если х есть целая переменная со значением 123, этот оператор выведет х = 123 за чем следует переход на новую строку в потоке сеют. Аналогично, если х имеет тип еотр!ех (Э22.5) со значением (1,2.4), то будет следующий результат вывода в поток сегж х= (1,2.4) Таким стилем записи можно пользоваться тогда, когда для типа определена операция «, а пользователь всегда это может сделать для новых типов. Операция вывода «нужна для того, чтобы избежать многословности, присущей именованным функциям вывода. Но почему именно «? Новый лексический знак ввести в язык С++ нельзя (Э!1.2). Можно было бы использовать знак операции присваивания д)и обозначения ввода/вывода, но многие люди предпочитают иметь для этих операций разные знаки.
Кроме того, операция = правоассоциативна, то есть сои~а=Ь означает соиг= (а=Ь), а не (саит=а) =Ь (й6.2). Я также пытался применить операции < и >, но их традиционный смысл «меньше чем» и «больше чем» так сильно застрял в головах людей, что применение этих значков в коде ввода/вывода бьно просто нечитаемым. Операции «и» не часто применяются ко встроенным типам, так что указанная проблема для этих операций не столь остра. Когда эти знаки операций применяются для ввода/вывода, я про себя читаю «как «записать в», а операцию»вЂ” как «прочесть из», Люди с сильной склонностью к технической терминологии часто называют эти операции как 1пзеггег и ехггасгог, соответственно'.
Приоритет операций «и» невысок, так что отсутствует нужда в дополнительных группирующих круглых скобках: сои) « "а*Ь»с=" «а*Ь«с « ' ~п' Круглые скобки требуются лишь для выражений, содержащих операции с приоритетом, более низким, чем у операций «и». Например: соиг « "а "Ы с=" «(а "Ы с) « ' ~п '; Операция сдвига влево 66.2.4) также может использоваться в выражениях вместе с операцией вывода, но конечно же, должна окружаться круглыми скобками: сои)« "а«Ь=" «(а«Ы « ' хп'; 21.2.1.
Потоки вывода Класс озтгеат реализует механизм преобразования значений различных типов в послейовательность символов. Обычно эти символы затем выводятся с применением низкоуровневых операций. Есть много видов символов (й20.2), которые можно охарактеризовать с помощью сйаг па(о (~20.2.1). Следовательно, озггеат является специализацией общего шаблона Ьая)с озггеат для конкретного вида символов: Нв русском языке эти термины не устоялись, в называть их «инзертер» н «экстрвктор» язык не поворачивается — дв и необходимости в этом нет никакой.
— Прим. ред. 21 2. Вывод зетрга1е<сгазз СЬ, с1азз Тг = сваг зга!!в<Се» сдззз зЫ::Ьаяс оягеат: пг!иа! рибдс Ьаяс !оз<СЬ, Тг> ( риЬ|с: г!г!иа! -Ьаяс оз!геат () ! 77 ... )! Этот шаблон и соответствуюшие операции вывода определены в пространстве имен зв1 и находятся в заголовочном файле <озвеат>, содержащим те средства файла <1оззгеат>, которые относятся к выводу. Параметры шаблона Ьаяс озггеат контролируют тип символов, используемых в реализации; они не влияют на типы выводимых значений. Потоки, реализованные для обычного типа сЬаг, и потоки «широких» символов, непосредственно поддерживаются каждой стандартной реализацией: зурейе/ Ьаяс оягеат <слог> оз!геат; зуреае/ Ьаяс оззгеат<тсдаг (> воз!геат; Для многих систем имеется возможность оптимизации вывода широких символов с помошью поззгеат до той степени, которую трудно достичь в потоках с единицей вывода в один байт.
Можно определить потоки, для которых физический ввод/вывод выполняется не в терминах символов. Однако такие потоки не соответствуют стандарту С+-ь и в данной книге не рассматриваются (В21.10[15[). Базовый класс Ьаяс юз представлен в заголовочном файле <1оз>. Он управляет форматированием 62!.4), локализацией 621.7) и доступом к буферам 621.6).
Он также определяет несколько типов ради удобства записи: !етр!аге<с)азз СЬ, с!от Тг = слог па(ь<СЬ» сгазз зИ:: Ьаяс 1оз: риЫ(с 1оз Ьазе ( риЫ!с: гуреИе/СЬ сдаг !уре! !уроде/ Тг !га(я гуре; Гуребе/'Зурепате Тг::!и! 1уре !и! !уре; /Утин целочисленного зноченил символов Зуребе/' Зурепате Тг:: роз !уре роз !уре; 77 позиция в буфере зуреде~'зурепате Тг:: о!)г (уре о1)г гуре; 77 смещение в буфере У см. также 32!.3.3, 32!.3.7, 32!.4.4, 32!.б3, и 32!.7.1 ... )! Класс Ьаяс 1оз запрещает копирование и создание объектов с помощью копируюшего конструктора (З!!.2.2). Соответственно, потоки озггеат и Ьз!геат нельзя копировать.