Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Название:Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:0101
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание
Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
переносимость
В идеальном случае функции fseek() и ftell() должны соответствовать модели Unix. Тем не менее, отличия в реальных системах иногда делают это невозможным. По этой причине стандарт ANSI предоставляет для этих функций пониженные ожидания. Далее описаны некоторые ограничения.
• В двоичном режиме реализации не обязаны поддерживать режим SEEK_END. Поэтому переносимость кода из листинга 13.4 не гарантируется. Более переносимый подход предусматривает чтение всего файла байт за байтом, пока не встретится конец. Но последовательное чтение файла для нахождения конца медленнее, чем просто переход в его конец. Директивы условной компиляции препроцессора С, обсуждаемые в главе 16, предлагают более систематизированный способ для поддержки выбора альтернативного кода.
• В текстовом режиме будут гарантированно работать только следующие вызовы
fseek():
548 глава 13
К счастью, многие распространенные среды делают возможными более строгие реализации этих функций.
функции fgetpos() И fsetpos()
Одна потенциальная проблема с функциями fseek() и ftell() заключается в том, что они ограничивают размеры файлов значениями, которые могут быть представлены типом long. Возможно, 2 миллиарда байтов могут показаться более чем достаточным размером, но постоянно растущие объемы устройств хранения позволяют работать с файлами больших размеров. В ANSI С появились две новых функции позиционирования, которые спроектированы на работу с файлами крупных размеров. Вместо применения для представления позиции значения long, они используют новый тип под названием fpos_t (от file position type — тин для позиции в файле). Тин fpos t не является фундаментальным, а определяется в терминах других типов. Переменная или объект данных типа fpos t может указывать позицию внутри файла и не может быть массивом, но его природа подобного и не требует. Реализация может предоставить какой-то тип, удовлетворяющий нуждам конкретной платформы; такой тип может быть реализован, например, в виде структуры.
В ANSI С определено, как применять тип fpos_t. Функция fgetpos() имеет следующий прототип:
int fgetpos(FILE * restrict stream, fpos_t * restrict pos);
Вызов fgetpos() помещает текущее значение тина fpos_t в ячейку, указанную pos; это значение описывает позицию в файле. Функция возвращает ноль в случае успеха и ненулевое значение при отказе.
Прототип функции fsetpos() выглядит гак:
int fsetpos(FILE *stream, const fpos_t *pos);
Вызов fsetpos() приводит к использованию значения типа fpos t из ячейки, заданной с помощью pos, для установки указателя файла в позицию, которую отражает это значение. Функция возвращает ноль в случае успеха и ненулевое значение при отказе. Значение fpos_t должно было быть получено предыдущим вызовом
fgetpos().
"За кулисами" стандартного ввода-вывода
Теперь, когда вы увидели некоторые возможности стандартного пакета ввода-вывода, мы займемся исследованием репрезентативной концептуальной модели, чтобы посмотреть, каким образом работает стандартный ввод-вывод.
Обычно первым шагом в применении стандартного ввода-вывода является вызов функции fopen() для открытия файла. (Однако вспомните, что файлы stdin, stdout и stderr открываются автоматически.)
Файловый ввод-вывод 549
Функция fopen() не только открывает файл, но и настраивает буфер (или два буфера для режимов чтения-записи) и устанавливает структуру данных, содержащую сведения о файле и о буфере. Кроме того, fopen() возвращает указатель на эту структуру, так что другие функции знают, где ее искать. Предположим, что это значение присвоено переменной типа указателя по имени fp. Говорят, что функция fopen() “открывает поток данных”. Если файл открывается в текстовом режиме, вы получаете текстовый поток, а если в двоичном — то двоичный поток.
Эта структура данных обычно включает индикатор позиции в файле, предназначенный для определения текущей позиции в потоке. Она также содержит индикаторы для ошибок и конца файла, указатель на начало буфера, идентификатор файла и счетчик количества байтов, действительно скопированных в буфер.
Давайте сосредоточим внимание на файловом вводе. Обычно следующим шагом является вызов одной из функций ввода, объявленных в stdio.h, таких как fscanf(), getc() или fgets(). Вызов любой такой функции приводит к тому, что порция данных копируется из файла в буфер. Размер буфера зависит от реализации, но обычно он имеет 512 или кратное этому числу количество байтов, такое как 4 096 или 16 384. (По мере увеличения объемов жестких дисков и памяти компьютера, выбираемые размеры буферов также имеют тенденцию к росту.) Вдобавок к заполнению буфера первоначальный вызов функции устанавливает значения в структуре, указываемой посредством fp. В частности, устанавливается текущая позиция в потоке данных и количество байтов, скопированных в буфер. Обычно текущая позиция начинается с байта 0.
После инициализации структуры данных и буфера функция ввода читает запрошенные данные из буфера. В результате индикатор позиции устанавливается так, чтобы указывать на символ, следующий за последним прочитанным символом. Поскольку все функции ввода из семейства stdio.h используют тот же самый буфер, вызов любой такой функции возобновляет чтение там, где оно было остановлено предыдущим вызовом любой из функций.
Когда функция ввода обнаруживает, что все символы из буфера прочитаны, она запрашивает копирование из файла в буфер следующей порции данных с объемом, равным размеру буфера. В такой манере функции ввода могут читать все содержимое вплоть до конца файла. После того, как функция прочитает последний символ финальной порции данных, она устанавливает индикатор конца файла в истинное значение. Следующий вызов любой функции ввода возвратит EOF.
Функции вывода в похожем стиле производят запись в буфер. Когда буфер заполняется, данные копируются в файл.
Другие стандартные функции ввода-вывода
Стандартная библиотека ANSI содержит более трех десятков функций, образующих семейство для стандартного ввода-вывода. Мы не будем раскрывать их все, но кратко опишем еще несколько функций, чтобы дать более четкое представление о том, что вообще доступно. Для каждой функции будет приведен прототип С, отражающий ее аргументы и возвращаемое значение. Все обсуждаемые здесь функции кроме setvbuf() также доступны в реализациях, предшествующих ANSI. В разделе V приложения Б представлен полный список пакета стандартного ввода-вывода ANSI С.
ФУНКЦИЯ intungetc (int с, FILE *fp)
Функция ungetc() заталкивает символ, указанный в с, обратно во входной поток. В случае заталкивания символа во входной поток он будет прочитан следующим вызовом стандартной функции ввода (рис. 13.2).
Читать дальшеИнтервал:
Закладка: