Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
stdio_ВАНЯ.rtf
Скачиваний:
5
Добавлен:
20.07.2019
Размер:
588.72 Кб
Скачать

Программный интерфейс потоков ввода-вывода

Программную реализацию операций обработки потоков ввода-вывода в языке C обеспечивает набор стандартных функций. Их объектный код сосредоточен в стандартной библиотеке объектных модулей системы программирования C. Программный интерфейс библиотечных функций ввода-вывода обеспечивает заголовочный файл stdio.h системы программирования C. Он декларирует прототипы всех функций ввода-вывода, содержит макроопределения для всех необходимых констант ввода-вывода и специфицирует массив структур для управления потоками.

Прототип каждой стандартной функции ввода-вывода определяет формат ее вызова, объявляя тип кода возврата и аргументов. Декларация прототипов необходима, если опции компилятора системы программирования C требуют выполнять контроль соответствия типов переменных, которые передаются в функцию, типам аргументов функции.

Макроопределения констант ввода-вывода в заголовочном файле <stdio.h> обеспечивает мобильность исходного кода программы, позволяя оперировать символическими макросами вместо конкретных значений констант, которые могут отличаться для различных реализаций системы программирования C. В частности, размер буфера потока в байтах задает макрос BUFSIZ, который имеет значение, кратное величине логического блока файловой системы, например, 512, 1024 или 4096 байт. При достижении конца потока ввода и при аварийном завершении большинство стандартных функций ввода-вывода возвращают значение, которое определяют макросы EOF и NULL. Обычно EOF обозначает отрицательное целое число (-1), а NULL ‑ нулевой указатель. Для идентификации терминальных потоков стандартного ввода, вывода и протокола диагностики используются макросы stdin, stdout и stderr. Для формального обозначения структуры управления потоком введен абстратный тип данных FILE.

Структура управления определяет базовый адрес буфера потока в сегменте данных программы, текущее смещение в буфере указателя чтения-записи, объем свободного места в буфере и номер дескриптора файла в контексте программы, который обеспечивает доступ к файловой системе для операций ввода-вывода через поток. Собственная структура управления формируется для каждого потока, который открывает программа для буферизованной обработки файлов. Адреса структур управления открытых потоков доступны в программе по указателю типа (FILE* ). Число потоков, которые могут быть одновременно открыты программой, ограничено набором файловых дескрипторов в контексте программы, которые индексируют открытые потоки в массиве структур управления. По умолчанию всегда открыты стандартные потоки ввода, вывода и протокола диагностики, которые индексируют младшие номера файловых дескрипторов 0, 1 и 2. Эти потоки обеспечивают поддержку стандартного терминального интерфейса программы. Потоки для обработки файлов индексируют старшие номера файловых дескрипторов. Они назначаются автоматически, когда в программе будут открыты потоки для буферизованной обработки файлов.

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

Начало обработки потока ввода-вывода

Чтобы открыть поток для буферизованной обработки файла используется библиотечная функция fopen. Спецификация формата ее вызова имеет вид:

FILE* fopen(const char* path, const char* mode);

Аргумент path функции fopen идентифицирует имя файла в файловой системе, для буферизованной обработки которого программа открывает поток. Аргумент mode устанавливает режим доступа к указанному файлу.

Функция fopen может устанавливать три базовых и три модифицированных режима доступа к файлу. Базовый режим доступа устанавливает одно из следующих значений аргумента mode: "r", "w" или "a". Спецификация "r" гарантирует последующее чтение данных из потока. Спецификация "w" означает усечение существующего файла до нулевой длины или создание нового файла и обеспечивает последующую запись данных в поток его обработки. Режим "a" позволяет добавлять данные из потока в конец существующего файла. Для нового файла режимы "a" и "w" эквивалентны. Любая базовая спецификация может быть дополнена модификатором "+", который задает комбинированный режим доступа к файлу: "r+", "w+" или "a+". Каждый из модифицированных режимов доступа позволяет открыть поток одновременно для чтения-записи данных файла, сохраняя свойства соответствующего базового режима.

Если для указанного файла требуемый режим доступа является допустимым, то функция fopen возвращает адрес соответствующей структуры управления потоком ввода-вывода. Этот адрес необходимо присвоить указателю типа (FILE* ), который принято называть указателем потока. Указатель потока идентифицирует открытый поток и текущее состояние обработки файла для последующих операций ввода-вывода. Он является обязательным явным или неявным аргументом стандартных функций буферизованного ввода-вывода, который обеспечивает их доступ к структуре управления потоком, пока поток открыт для обработки. При нарушении прав доступа к файлу функция fopen возвращает нулевой указатель NULL, устанавливая состояние ошибки. Следующий фрагмент исходного кода демонстрирует классическую схему использования функции fopen, чтобы открыть поток для обработки:

FILE* input; /* указатель потока ввода */

/* Открыть поток ввода данных файла any.txt */

if((input = fopen("any.txt", "r") == NULL) {

/* Диагностика и обработка ошибки, если */

/* файл any.txt недоступен для чтения */

} /* if */

/* Обработка потока */

По умолчанию, файловый поток, который корректно открыт функцией fopen, буферизуется по блокам, размером BUFSIZ байт, для последующих операций ввода-вывода. Необходимый объем памяти для буфера потока распределяется автоматически в адресном пространстве структуры управления потоком при первом обращении к функциям буферизованного ввода-вывода. Терминальные потоки стандартного ввода-вывода буферизованы по строкам, а стандартный поток диагностики не буферизован. Эти потоки гарантированно открыты и не требуют обращения к функции fopen для начала обработки. Для обращения к стандартным потокам макроопределены указатели stdin, stdout и stderr типа (FILE* ), которые в явной или неявной форме передаются функциям буферизованного ввода-вывода.

Форматный вывод

Форматный вывод есть специальная разновидность буферизованного вывода, где запись информации в поток сопровождается форматным преобразованием данных базовых типов. Характер преобразования обеспечивает требуемый символьный формат вывода данных в поток. В системе программирования C форматный вывод реализуют функции fprintf, printf и sprintf.

Универсальную возможность форматирования вывода данных базовых типов для их записи в файловый или стандартный поток предоставляет функция fprintf. Спецификация формата ее вызова имеет вид:

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]