- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
Шрифт:
Интервал:
Закладка:
Б.10.2. Семейство функций printf()
Наиболее популярными функциями в стандартной библиотеке языка С являются функции ввода-вывода. Тем не менее рекомендуем использовать библиотеку iostream, потому что она безопасна с точки зрения типов и допускает расширение. Функция форматированного вывода printf() используется очень широко (в том числе и в программах на языке C++) и часто имитируется в других языках программирования.
В каждой версии число n — это количество записанных символов, а в случае неудачи — отрицательное число. На самом деле значение, возвращаемое функцией printf(), практически всегда игнорируется.
Объявление функции printf() имеет следующий вид:
int printf(const char* format ...);
Иначе говоря, эта функция получает строку в стиле языка С (как правило, строковый литерал), за которой следует список, состоящий из произвольного количества аргументов произвольного типа. Смысл этих дополнительных аргументов задается спецификаторами преобразования в форматной строке, например %c (вывести символ) и %d (вывести целое число). Рассмотрим пример.
int x = 5;
const char* p = "asdf";
printf("Значение x равно '%d', а значение p равно '%s'n",x,s);
Символ, следующий за знаком % управляет обработкой аргументов. Первый знак % применяется к первому дополнительному аргументу (в данном примере спецификатор %d применяется к переменной x), второй знак % относится ко второму дополнительному аргументу (в данном примере спецификатор %s применяется к переменной p) и т.д. В частности, рассмотренный выше вызов функции printf() приводит к следующему результату:
Значение x равно '5', а значение p равно 'asdf'
Затем происходит переход на новую строку.
В принципе соответствие между директивой преобразования % и типом, к которому она применяется, проверить невозможно. Рассмотрим пример.
printf("Значение x равно '%s', а значение p равно '%d'n",x,p); // ой!
Набор спецификаторов преобразования довольно велик и обеспечивает большую гибкость (а также много возможностей сделать ошибку). За символом % могут следовать спецификаторы, описанные ниже.
Нулевая или слишком маленькая ширина поля никогда не приводит к усечению вывода; дополнение вывода нулями или пробелами производится только тогда, когда заданная ширина поля превышает реальную.
Поскольку в языке C нет пользовательских типов в смысле языка C++, в нем нет возможностей для определения форматов вывода для таких классов, как complex, vector или string.
Стандартный поток вывода stdout в языке C соответствует потоку cout. Стандартный поток ввода stdin в языке С соответствует потоку cin. Стандартный поток сообщений об ошибках stderr в языке С соответствует потоку cerr. Эти соответствия между стандартными потоками ввода-вывода в языке C и C++ настолько близки, что потоки ввода-вывода как в стиле языка С, так и стиле языка С++ могут использовать один и тот ж буфер. Например, для создания одного и того же потока вывода можно использовать комбинацию операций над объектами cout и stdout (такая ситуация часто встречается в смешанном коде, написанном на языка С и С++). Эта гибкость требует затрат. Для того чтобы получить более высокую производительность, не смешивайте операции с потоками из библиотек stdio и iostream при работе с одним и тем же потоком, вместо этого вызывайте функцию ios_base::sync_with_stdio(false) перед выполнением первой операции ввода-вывода. В библиотеке stdio определена функция scanf(), т.е. операция ввода, похожая на функцию printf(). Рассмотрим пример.
int x;
char s[buf_size];
int i = scanf("Значение x равно '%d', а значение s равно '%s'n",&x,s);
Здесь функция scanf() пытается считать целое число в переменную x и последовательность символов, не являющихся разделителями, в массив s. Неформатные символы указывают, что они должны содержаться в строке ввода. Рассмотрим пример.
"Значение x равно '123', а значение s равно 'string 'n"
Программа введет число 123 в переменную x и строку "string", за которой следует 0, в массив s. Если вызов функции scanf() завершает работу успешно, результирующее значение (i в предыдущем вызове) будет равно количеству присвоенных аргументов-указателей (в данном примере это число равно 2); в противном случае оно равно EOF. Этот способ индикации ввода уязвим для ошибок (например, что произойдет, если вы забудете вставить пробел после строки "string" в строке ввода?). Все аргументы функции scanf() должны быть указателями. Мы настоятельно рекомендуем не использовать эту функцию.
Как же ввести данные, если мы вынуждены использовать библиотеку stdio? Один и из распространенных ответов гласит: “Используйте стандартную библиотечную функцию gets()”.
// очень опасный код:
char s[buf_size];
char* p = gets(s); // считывает строку в массив s
Вызов p=gets(s) будет вводить символы в массив s, пока не обнаружится символ перехода на новую строку или не будет достигнут конец файла. В этом случае в конец строки s после последнего символа будет вставлен 0. Если обнаружен конец файла или возникла ошибка, то указатель p устанавливается равным NULL (т.е. 0); в противном случае он устанавливается равным s. Никогда не используйте функцию gets(s) или ее эквивалент scanf("%s",s))! За прошедшие годы создатели вирусов облюбовали их слабые места: генерируя вводную строку, переполняющую буфер ввода (в данном примере строку s), они научились взламывать программы и атаковать компьютеры. Функция sprintf() страдает от таких же проблем, связанных с переполнением буфера.
Библиотека stdio содержит также простые и полезные функции чтения и записи символов.
Обратите внимание на то, что результатом этих функций является число типа int (а не переменная типа char или макрос EOF). Рассмотрим типичный цикл ввода в программе на языке С.
int ch; /* но не char ch; */
while ((ch=getchar())!=EOF) { /* какие-то действия */ }
Не применяйте к потоку два последовательных вызова ungetc(). Результат такого действия может оказаться непредсказуемым, а значит, программа не будет переносимой.
Мы описали не

