- •1 Понятие алгоритма формы представления алгоритмов
- •2 Линейные и разветвляющиеся алгоритмы.
- •3 Циклические алгоритмы
- •4 Понятие прикладного и системного программирования
- •5 Структура программ на языке си
- •6 Арифметико-логические операции над переменными
- •Арифметические операции
- •Операции увеличения и уменьшения
- •Операции "увеличить на", "домножить на" и т.П.
- •Логические операции
- •Операции сравнения
- •Побитовые логические операции
- •7 Два вида оператора выбора Оператор if
- •8 Понятие цикла
- •1.4.6. Оператор break
- •1.4.7. Оператор for
- •1.4.8. Оператор while
- •1.4.9. Оператор do while
- •1.4.10. Оператор continue
- •1.4.11. Оператор return
- •9 Массив
- •12 Указатели
- •13 Адресная арифметика
- •14 Операции над указателями
- •15 Массивы указателей
- •16 Указатели на функции Указатели на функции
- •17 Структуры
- •18 Доступ к элементам структуры
- •19 Структуры как аргументы
- •6.2. Структуры и функции
- •20 Динамические структуры на массиве
- •21 Динамическое распределение памяти Функции динамического распределения
- •Динамическое выделение памяти для массивов
- •23 Организация доступа к файлам
- •Закрытие потока при помощи fclose
- •Чтение из потока при помощи fgetc
- •«Ловушка» eof
- •При помощи fgets
- •24 Форматированный ввод –вывод Функции форматированного ввода и вывода в си
- •Спецификатор типа
- •Спецификатор типа
- •25 Верификация тестирование отладка программ
- •Введение
- •26 Причины и последствия появления ошибок
- •27 Идея модульного программирования
- •28 Технология проектирования сверху-вниз
- •29 Итерация рекурсия
- •30 Методы сортировки
- •34 Способы защиты информации
Закрытие потока при помощи fclose
Функция fclose принимает один аргумент: указатель на структуру FILE потока для закрытия.
int fclose(FILE *fp);
Функция возвращает нуль в случае успеха и EOF в случае неудачи. При нормальном завершении программы функция вызывается автоматически для каждого открытого файла.
Чтение из потока при помощи fgetc
Функция fgetc применяется для чтения символа из потока.
int fgetc(FILE *fp);
В случае успеха, fgetc возвращает следующий байт или символ из потока (зависит от того, файл «двоичный» или «текстовый» (как выше обсуждалось). В противном случае, fgetc возвращает EOF. (Отдельный тип ошибок можно определить вызовом ferror или feof с указателем на файл.)
Стандартный макрос getc также определен в <stdio.h>, успешно работая как fgetc, кроме одного: будучи макросом, он может обрабатывать свои аргументы более одного раза.
Стандартная функция getchar также определена в <stdio.h>, она не принимает аргументов, и эквивалентна getc(stdin).
«Ловушка» eof
Распространенной ошибкой является использование fgetc, getc или getchar для присваивания результата переменной типа char перед сравнением его с EOF. Следующий фрагмент кода демонстрирует эту ошибку, а рядом приведен корректный вариант:
Ошибка |
Правильно |
char c; while ((c = getchar()) != EOF) { putchar(c); } |
int c; while ((c = getchar()) != EOF) { putchar(c); } |
Нужно учитывать систему, в которой тип char, длина которого составляет 8 бит (в частности, архитектура x86), представляет 256 различных значений. getchar может возвращать любой из 256 возможных символов, а также может возвращать EOF для обозначения конца файла, значение которого не может совпадать ни с одним из значений char.
Когда результат getchar присваивается переменной типа char, которая может представить лишь 256 различных значений, происходит вынужденная потеря информации — при сжатии 257 значений в 256 «мест» происходит коллизия. Значение EOF при конвертации в char становится неотличимым от любого из остальных 256 символов. Если этот символ обнаружен в файле, код, приведенный выше, может принять его за признак конца файла, или, что еще хуже, если тип char — беззнаковый, тогда с учетом того, что EOF — значение отрицательное, оно никогда не сможет стать равным любому беззнаковому char, и таким образом, пример выше не закончится на метке конца файла, а будет выполняться вечно, повторно печатая символ, получающийся при конвертации EOF в char.
В системах, где int и char одинакового размера[каких?][источник не указан 507 дней], даже «правильный» вариант будет работать некорректно из-за сходства EOF и другого символа. Правильным вариантом обработки подобной ситуации является проверка feof и ferror после того, как getchar вернет EOF. Если feof определит, что конец файла еще не достигнут, а ferror «сообщит», что ошибок нет, то EOF, возвращенный getchar может считаться текущим символом. Такие дополнительные проверки делаются редко, так как большинство программистов считает, что их код никогда не будет выполняться на подобных системах с «большим char». Другой способ состоит в использовании проверки при компиляции, что UINT_MAX > UCHAR_MAX, которая хотя бы предотвратит компиляцию на подобных системах.