Бьерн Страуструп. Язык программирования С++. Специальное издание (2011) (1004033), страница 162
Текст из файла (страница 162)
Если установлена точность вывода или указана спецификация —, то этот пуль игнорируется; 768 Глава 21. Потоки $ необязательный знак (рещетка), означающий: что числа с плавающей запятой выводятся с точкой, даже если после точки значащих цифр нет; что выводятся «хвостовые«нули; что восьмеричные значения выводятся с лидирующим нулем; что шестнадцатеричные значения предваряются Ох или ОХ, с1 необязательная последовательность цифр, задающая ширину поля; если преобразованное число имеет меньшее число символов, чем ширина поля, то поле будет дополнено пробелами слева (или справа — если указан индикатор выравнивания влево); если число И указано с начальным нулем, то заполнение вместо пробелов выполняется нулями; необязательная точка, которая служит для отделения ширины поля от последующей строки цифр; с) необязательная последовательность (строка) цифр, задающая точность, и которая означает число цифр после десятичной точки для е и г форматов, или максимальное число выводимых символов; * ширина поля или точность могут быть указаны звездочкой — в этом случае их величину задает целочисленный аргумент; 1т необязательный символ, указывающий, что последующие И, о, х или и относятся к целочисленному аргументу типа заогг, 1 необязательный символ, указывающий, что последующие И, о, х или и относятся к целочисленному аргументу типа Гоия; т.
необязательный символ, указывающий, что последующие е, Е, и, С или у'относятся к типу ОоиЫе; ««этот символ требует вывести символ ь (никакие аргументы при этом не используются); с символ, указывающий тип преобразования; применяются следующим символы преобразований: о Целый аргумент преобразуется к десятичному виду; т Целый аргумент преобразуется к десятичному виду; о Целый аргумент преобразуется к восьмеричному виду; х Целый аргумент преобразуется к шестнадцатеричному виду; х Целый аргумент преобразуется к шестнадцатеричному виду; б Аргумент типа Гтоат или ИоиЫе преобразуется к десятичному виду (-)ЙЫ.ЙЫ; количество цифр после запятой соответствует точности, указанной для этого аргумента; при необходимости число округляется; если точность не задана, выводится б цифр; если для точности указан О, а а не используется, то ни цифры, ни точка не выводятся; е Аргумент типагтоаг или ОоиЫе преобразуется к десятичной нотации в научном стиле Ят)лЫйе+гЫ или (-)гт.агЫе-тЫ, где до точки стоит одна цифра, а количество цифр после точки соответствует указанной для аргумента точности; при необходимости число округляется; если точность не задана, выводится 6 цифр; если для точности указан О, а о не используется, то ни цифры, ни точка не выводятся; 2) 8.
Ввод/выводязыка С 769 Совпадает с предыдущим случаем, но буква е выводится в верхнем регистре — как Е; Аргумент типаЯоаг или ИоиЫе выводится в стиле е(,1'или е в зависимости от того, что дает максимальную точность при минимуме занимаемого места; Совпадает с предыдущим случаем, но буква е выводится в верхнем регистре — как Е; с Выводится символьный аргумент; нулевые символы игнорируются; з Аргумент трактуется как строка (указатель на символы), и символы строки выводятся до тех пор, пока не встретится нулевой символ, или пока не исчерпается количество символов, указанное точностью; если точность отсутствует или указана как О, то вывод продолжается до нулевого символа; р Аргумент трактуется как указатель; конкретный вид представления значения указателя зависит от реализации; ц Целый аргумент без знака преобразуется к десятичной нотации; и Количество символов, выведенное к этому моменту функциями рг!пр(), 1рг!пЯ ) или ерг/пЯ(), записывается в аргумент типа 1иг, указуемый через указатель типа тг*.
Не указанная или недостаточная ширина поля не приводят к урезанию значений; дополнение символами-заполнителями имеет место тогда, когда указанная ширина поля превосходит необходимую ширину. Вот более сложный пример сваг* !!пе /огтаг = "$6пе %д ~" зьл'~" '~п"; 1пг Дие = 13; спас* 1)1е пате = "С+ь/та!и.с"; рг!и(3("1пг а> ~и"); рг/п(!'(11ие /оста!, 1те, 1)1е пате); в результате чего будет выведено 1пг а; Ф!1ие 13 "С++/та!п.с" Использование рг1и~() небезопасно в том смысле, что никакой проверки типа при этом не выполняется.
Вот известный пример, как получить непредсказуемый вывод, вывод некоторого участка памяти или чего похуже: сйагх = 'д'; рг!иЯ" Ьаг!!при( сйаг: %з",х); //вместо лт должно быть глс В то же время, функция рг1п11'() обеспечивает чрезвычайную гибкость, и она хорошо знакома программирующим на языке С. Аналогично, аегс1игг() часто применяется для ввода символов: !пг г; пт!1е ( (1=дегсйаг () ) ! = ЕОР) ( /* испол уем ! * / ) Чтобы можно было проверять конец ввода посредством сравнения с целочисленным ЕОЕ, возврат «егс!гаг() нужно сохранять в переменной типа !иг, а не сйаг.
Глава 21. Потоки Подробнее со вводом/выводом в стиле языка С можно ознакомиться по справочной литературе или по книге «Т))е С Ргойгапнпщй 1.апйиа8е» [Кеппй)зап, В1(с)))е, 1988[. 21.9. Советы 1. 2. 3. 4. 5. 6. 8. 9. 10. 11. 12. 13. 14. 15.
16. 17. 18. 19. Определяйте операции «и» для пользовательских типов с очевидными текстовыми представлениями их значйний; 821.2.3, 821.3.5. При выводе выражений с операциями, имеющими низкий приоритет, поль- зуйтесь круглыми скобками; 821.2. Для добавления операций «или» нет необходимости в модификации Ыгеат или озпеат; 821.2.3. Вы можете определить функцию, которая ведет себя как виртуальная по вто- рому аргументу; 821.2.3.1. Помните, что по умолчанию операция» пропускает пробельные символы; 821.3.2. Используйте низкоуровневые функции ввода вроде яег() и геохи() в основ- ном при реализации высокоуровневых функций ввода; 821.3.4.
Используя лег(), аегйпе() и гоаб(), будьте внимательны в отношении крите- рия конца ввода; 821.3.4. Для управления вводом/выводом вместо флагов состояния применяйте ма- нипуляторы; 521.3.3, 52!.4, 521.4.6. Применяйте исключения только для перехвата редких ошибок ввода/вывода; $21.3.6. Связывайте потоки,' используемые для интерактивного ввода и вывода; 821.3.7. Используйте часовых для концентрации начального и завершающего кода многих функций в одном месте; 821.3.8. Не применяйте круглые скобки для манипуляторов без аргументов; $21.4.6.2. Используя стандартные манипуляторы, не забывайте включать 4(ле!и»1е <1отал[р>; 821.4.6.2. Вы можете достичь эффекта (и эффективности) тернарной операции, опре- делив простой функциональный класс; в21.4.6.3.
Помните, что спецификация мЫгл относится лишь к ближайшей операции ввода/вывода; 821.4.4. Помните, что спецификация ргесвюп относится ко всем последующим опе- рациям вывода чисел с плавающей запятой; 821.4.3. Используйте строковые потоки для форматирования в памяти; 821.5.3. Вы можете задать режим работы файлового потока; 821.5.1. Расширяя систему ввода/вывода, четко различайте форматирование (1озпеат) и буферизацию (хггеат0иЯ; 821.1, 821.6. 771 2).10 Упражнения 21.10. Упражнения 20.
21. 22. 23. 24. 25. 26. 27. 1. 3. 4. 5. 6. Реализуйте нестандартные способы передачи значений через буферы пото- ков; 821.6.4. Реализуйте нестандартные способы форматирования значений через опера- ции над потоками; 821.2.3, 821.3.5. Вы можете изолировать и инкапсулировать обращение к пользовательскому коду с помощью соответствующей пары функций; 821.6.4. Вы можете использовать т ага(1 () для того, чтобы заранее убедиться в воз- можности операции ввода; 821.6.4. Различайте простые эффективные операции и операции, реализующие стра- тегию: первые делайте встраиваемыми, а вторые — виртуальными; 821.6.4.
Для отражения национальных особенностей применяйте класс 1оса!е; 821.7. Для смешения или разъединения буферов ввода/вывода языков С и С++ вы- зывайте лупе тУЬ зЫ1о(); 821.8. Применяя ввод/вывод в стиле С, помните об ошибках, связанных с типами; $21.8. (*1.5) Прочитайте файл, содержащий числа с плавающей запятой, скомбинируйте пары прочитанных чисел в комплексные значения и выведите их. (*1.5) Определите тип Лате атг айЬех«. Определите операции «и» для этого типа. Скопируйте поток объектов типа Фате ат( айЬ.ехт. ('2.5) Скопируйте поток объектов типа Жете атг' айЬек«и вставьте в него столько ошибок, сколько сумеете придумать (например, ошибки форматирования, или ошибочное определение конца строк).
Обработайте эти ошибки таким образом, чтобы функция копирования смогла прочитать большинство из корректно отформатированных объектов типа%ате атг а«Ыгех«, несмотря на то, что на входе «хорошие» значения будут чередоваться с «плохими». (*2.5) Переопределите формат ввода/вывода объектов типа Фате апН а~Ыгехз так, чтобы он стал менее чувствительным к ошибкам ввода.
("2.5) Разработайте ряд функций для запроса и чтения информации различного типа. Подсказка: целые числа, числа с плавающей запятой, имена файлов, почтовые адреса, даты, персональная информация и т.д. Попытайтесь защитить функции от ошибок ввода («защита от дурака»). (*1.5) Напишите программу, которая выводит; все буквы нижнего регистра, все буквы, все буквы и цифры, все символы из идентификаторов С++ вашей системы, все знаки препинания, числовые коды управляющих символов, все терминальные символы, все коды терминальных символов и, наконец, все печатные символы.