WikiSort.ru - Не сортированное

ПОИСК ПО САЙТУ | о проекте

gets — функция, входящая в Стандартную библиотеку языка Си, объявляемая в заголовочном файле stdio.h, которая считывает строку стандартного ввода и помещает её в буфер, созданный вызывающей функцией.

Реализация

Может быть реализована следующим способом (при помощи getchar):

char *gets(char *s)
{
/*очистка буфера ввода */
fflush(stdin);

    int i, k = getchar();

    /* Возвращаем NULL если ничего не введено */
    if (k == EOF)
        return NULL;

    /* Считываем и копируем в буфер символы пока не достигнем конца строки или файла */
    for (i = 0; k != EOF && k != '\n'; ++i) {
        s[i] = k;
        k = getchar();

        /* При обнаружении ошибки результирующий буфер непригоден */
        if (k == EOF && !feof(stdin))
            return NULL;
    }

    /* Нуль-терминируем и возвращаем буфер в случае успеха.
    Символ перевода строки в буфере не хранится. */
    s[i] = '\0';

    return s;
}

Программист должен знать максимум числа символов, которые должны быть считаны gets, чтобы удостовериться, что выделяется буфер достаточного размера. Подобное невозможно без информации о данных. Эта проблема может приводить к созданию ошибок и открывает простор для нарушений компьютерной безопасности при помощи переполнения буфера. Многие источники советуют программистам никогда не использовать gets в новых программах[1][2][3].

Применение gets весьма осуждается. Функция оставлена в стандартах C89 и C99 для обратной совместимости. Множество инструментов разработки ПО, как например, GNU ld выдает предупреждения в случае обнаружения при компоновке кода с использованием gets.

Альтернативы

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

char buffer[BUFFERSIZE];
gets(buffer);

кодом вида

char buffer[BUFFERSIZE];
fgets(buffer, sizeof(buffer), stdin);

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

Безопасность использования

Безопасное использование gets требует от программиста проверки того, что переполнение буфера не станет проблемой. Стандарт языка Си этого не гарантирует; тем не менее, существует несколько относительно усложненных способов проверки этого с различной степенью переносимости. Одним из возможных вариантов является защитная страница для защиты памяти. В сочетании с обработчиками исключений, такими как SIGSEGV и sigaction, защитная страница может помочь с обработкой ошибок.

Примечания

  1. GNU. GNU Библиотека Си — Строковый Ввод. — «Функция gets весьма опасна, так как она не обеспечивает никакой защиты от переполнения строки s. Библиотека GNU включает её только ради совместимости. Вам следует всегда использовать вместо неё fgets или getline.». Проверено 2 августа 2008. Архивировано 19 марта 2012 года.
  2. Почему все говорят не использовать gets()?. comp.lang.c Часто Задаваемые Вопросы. Проверено 2 августа 2008. Архивировано 19 марта 2012 года.
  3. gets(3)  страница справки man по библиотечным функциям GNU/Linux  (англ.) — «Никогда не используйте gets(). Так как невозможно сказать, не зная ничего о данных, сколько символов будет прочитано gets(), и поэтому gets() продолжит помещать символы в буфер и после его заполнения, что весьма опасно в использовании. Это способно нарушить информационную защиту компьютерной системы.»

Ссылки

Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".

Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.

Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .




Текст в блоке "Читать" взят с сайта "Википедия" и доступен по лицензии Creative Commons Attribution-ShareAlike; в отдельных случаях могут действовать дополнительные условия.

Другой контент может иметь иную лицензию. Перед использованием материалов сайта WikiSort.ru внимательно изучите правила лицензирования конкретных элементов наполнения сайта.

2019-2024
WikiSort.ru - проект по пересортировке и дополнению контента Википедии