Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015

Тут можно читать онлайн Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - бесплатно полную версию книги (целиком) без сокращений. Жанр: Прочая старинная литература, издательство Вильямс, год 0101. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.

Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание

Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - описание и краткое содержание, автор Стивен Прата, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)

Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать книгу онлайн бесплатно, автор Стивен Прата
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

После установки пространства для строки ее можно прочитать. Библиотека С предлагает три функции, позволяющие считывать строки: scanf(), gets() и fgets(). Чаще других используется функция gets(), поэтому мы обсудим ее первой.

Неудачливая функция gets()

Вспомните, что при чтении строки функция scanf() и спецификатор %s обеспечивают считывание только одного слова. Однако часто желательно, чтобы программа могла читать сразу всю вводимую строку, а не одиночное слово. Именно такой цели на протяжении многих лет служила функция gets(). Это простая и легкая в использовании функция. Она читает всю строку вплоть до символа новой строки, отбрасывает этот символ и сохраняет остальные символы, добавляя нулевой символ, чтобы образовать строку С. Часто эта функция применяется в сочетании с функцией puts(), которая отображает с троку с добавлением в конце символа новой строки. В листинге 11.6 приведен короткий пример.

Листинг 11.6. Программа getsputs. с

Символьные строки и строковые функции 431 Вот как мог бы выглядеть результат - фото 330

Символьные строки и строковые функции 431

Вот как мог бы выглядеть результат пробного запуска программы раньше Введите - фото 331

Вот как мог бы выглядеть результат пробного запуска программы раньше:

Введите строку.

Я хотел бы ознакомиться с теорией работы со строками!

Ваша строка, выведенная дважды:

Я хотел бы ознакомиться с теорией работы со строками!

Я хотел бы ознакомиться с теорией работы со строками!

Готово.

Обратите внимание, что вся введенная строка кроме символа новой строки сохраняется в массиве words, а вызов puts (words) обеспечивает такой же эффект, как и вызов printf("%s\n", words).

А вот так выглядит более новый вывод:

Введите строку.

warning: this program uses gets(), which is unsafe.

Предупреждение: эта программа использует функцию gets О, что небезопасно.

О, нет!

Ваша строка, выведенная дважды:

О, нет!

О, нет!

Готово.

Компилятор предпринял довольно необычное действие, вставив предупреждение в вывод программы! Таким образом, это сообщение будет отображаться при каждом запуске этой программы. Не все компиляторы будут поступать подобным образом. Некоторые из них могут выдавать предупреждение на этапе компиляции, но это не настолько привлекает внимание.

В чем же состоит проблема? Дело в том, что функция gets() не делает проверку, умещается ли вводимая строка в массив. Учитывая, что единственным аргументом функции является words, она просто не в состоянии выполнить такую проверку. Вспомните, что имя массива преобразуется в адрес его первого элемента. Следовательно, функции gets() известно только то, где начинается массив, но не то, сколько элементов в нем содержится.

Если строка ввода окажется слишком длинной, возникнет переполнение буфера — другими словами, символы переполнят предназначенное для них целевое пространство. Лишние символы мтут просто попасть в неиспользуемую память и привести к проблемам, которые проявятся не сразу, или же они могут перезаписать другие данные в программе. Й это — отнюдь не все возможные варианты. Ниже приведен пример запуска программы, в которой значение STLEN было переустановлено в 5, чтобы сделать переполнение буфера более вероятным.

Введите строку.

warning: this program uses gets(), which is unsafe.

Предупреждение: эта программа использует функцию gets О, что небезопасно,

Думаю, все будет отлично.

432 глава 11

Ваша строка, выведенная дважды:

Думаю, все будет отлично.

Думаю, все будет отлично.

Готово.

Segmentation fault: 11

Ошибка сегментации: 11

“Ошибка сегментации” звучит не слишком здорово, правда? В системе Unix такое сообщение указывает на то, что программа попыталась получить доступ в память, которая не была для нее выделена.

К сожалению, язык С предоставляет много возможностей для того, чтобы неудачное программирование приводило к обескураживающим и трудно отслеживаемым ошибкам. Почему же тогда только недостаток функции gets() удостоен особого внимания? Вероятно потому, что ее непредсказуемое поведение создает риск для безопасности. В прошлом злоумышленники пользовались особенностями системных программ, в которых применялась функция gets(), для вставки и выполнения кода, который компрометировал безопасность системы.

На определенном этапе многие представители сообщества программистов на С рекомендовали исключить функцию gets() из программного словаря. Комитет, создавший стандарт С99, также опубликовал обоснование стандарта. В этом обосновании были признаны проблемы, связанные с использованием функции gets(), и применять ее не рекомендовалось. Вместе с тем в обосновании оправдывалось сохранение функции gets() в качестве части стандарта из-за ее удобства в случае корректного использования, а также из-за того, что она была частью огромного объема существующего кода.

Тем не менее, комитет по созданию стандарта С11 придерживался более строгих взглядов и исключил функцию gets() из стандарта. С другой стороны, стандарт определяет то, что компилятор должен поддерживать, а не то, что он не должен поддерживать. На практике большинство компиляторов продолжают поддерживать эту функцию ради обратной совместимости. Но, как это имеет место с применяемым нами компилятором, это отнюдь не идет ему на пользу.

Альтернативы функции gets()

Традиционной альтернативой gets() является функция fgets(), которая обладает несколько более сложным интерфейсом и немного по-другому обрабатывает вводимые данные. Кроме того, в стандарте C11 к общему набору добавлена функция gets s(). Она больше похожа на gets() и ее легче использовать в существующем коде в качестве замены. Тем не менее, она является частью необязательного расширения семейства функций ввода-вывода stdio.h, поэтому компиляторы С стандарта СИ не обязаны ее поддерживать.

Функция fgets о (И fputs())

Функция fgets() предотвращает возможную проблему переполнения, принимая второй аргумент, который ограничивает количество считываемых символов. Эта функция предназначена для файлового ввода, что несколько затрудняет ее применение. Ниже перечислены ее отличия от функции gets().

• Она принимает второй аргумент, задающий максимальное количество символов для чтения. Если этот аргумент имеет значение n, то функция fgets() прочитает п-1 символов или будет читать до появления символа новой строки в зависимости от того, что произойдет раньше.

Символьные строки и строковые функции 433

• Если функция fgets() сталкивается с символом новой строки, она сохраняет его в строке, в отличие от функции gets(), которая отбрасывает его.

• Функция fgets() принимает третий аргумент, указывающий файл, из которого должно производиться чтение. Для чтения с клавиатуры в качестве этого аргумента используется stdin (от standard input— стандартный ввод); этот идентификатор определен в stdio.h.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Стивен Прата читать все книги автора по порядку

Стивен Прата - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Язык программирования C. Лекции и упражнения (6-е изд.) 2015 отзывы


Отзывы читателей о книге Язык программирования C. Лекции и упражнения (6-е изд.) 2015, автор: Стивен Прата. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x