рефераты конспекты курсовые дипломные лекции шпоры

Реферат Курсовая Конспект

Лекция 29-30

Лекция 29-30 - Лекция, раздел Информатика, Лекция 29-30   Потоковый Ввод-Вывод   ...

 

Потоковый ввод-вывод

 

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

Данные, поступающие в поток, как правило, буферизуются, то есть помещаются в специальный буфер данных, в котором они могут храниться. Передача данных из буфера получателю данных происходит при запросе от получателя или в случае заполнения буфера данных. Если получатель производит чтение данных, когда буфер потока пуст, то данная ситуация расценивается как достижение конца потока, как правило функции, работающие с потоками, в данном случае возвращают константу EOF (равную -1), определённую в файле stdio.h.

Существуют два основных типа ввода-вывода: форматированный и неформатированный. При форматированном вводе-выводе производится преобразование типов и структуры данных. При неформатированном вводе-выводе подобное преобразование не производится. Например, при форматированном выводе числа типа float функцией printf() можно задавать форму отображения числа на экране. Форматированный и неформатированный ввод-вывод выполняется соответствующими функциями ввода-вывода.

Поток для работы может быть отрыт в текстовом или бинарном режиме. Если поток открыт в текстовом режиме, то нет однозначного соответствия между данными, помещаемыми в поток, и данными, извлекаемыми из потока (например, символ ‘n’ при выводе на экран преобразуется в пару символов: перевод строки и возврат каретки, а символ ‘Ctrl+Z’ интерпретируется как EOF). Если поток открыт в бинарном режиме, то данные, помещаемые в поток, однозначно соответствуют данным, извлекаемым из потока. Это существенно при работе с символьной информацией, содержащей escape-последовательности.

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

Все потоки и функции для работы с ними объявлены в файле stdio.h.

 

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

Отличие потока от файла заключается в том, что поток представляет собой абстрактный уровень доступа программиста к физическому устройству, а файл представляет собой способ хранения информации на этом физическом устройстве.

Операция открытия файла связывает поток с определённым файлом, операция закрытия разрывает эту связь. Каждый поток, связанный с файлом, имеет управляющую структуру типа FILE. Указатель на данную структуру, называемый также указателем на файловую переменную, является связующим звеном между потоком и файлом, работа с потоком, а значит, и со связанным с ним файлом, осуществляется через связанный с потоком указатель на файловую переменную. Работа с потоком, который не связан ни с каким файлом, либо невозможна, либо может привести к неправильной работе как программы, так и системы в целом.

 

Указатель на файловую переменную.

В заголовочном файле stdio.h следующая структура объявлена как файловая переменная:

 

typedef struct {

int level;

unsigned flags;

char fd;

unsigned char hold;

int bsize;

unsigned char *buffer;

unsigned char *curp;

unsigned istemp;

short token;

} FILE;

 

Поле level определяет состояние буфера (пуст, полон), поле flags – флаги состояния файла, поле fd – дескриптор (префикс) файла, поле hold – непереданный символ, поле bsize – размер внутреннего буфера, поле buffer – указатель на буфер данных, поле curp – текущий указатель чтения-записи файла, поле istemp – флаг временного файла, поле token – права доступа к файлу. Поле flags может иметь следующие значения, определенные как макросы.

 

Макрос Значение Пояснение
_F_RDWR 0x0003 Файл открыт для чтения и записи
_F_READ 0x0001 Файл открыт только для чтения
_F_WRIT 0x0002 Файл открыт только для записи
_F_BUF 0x0004 Имеется буфер данных
_F_LBUF 0x0008 Построчно буферизуемый файл
_F_ERR 0x0010 Индикатор ошибки
_F_EOF 0x0020 Индикатор EOF
_F_BIN 0x0040 Индикатор бинарного файла
_F_IN 0x0080 Буфер содержит входные данные
_F_OUT 0x0100 Буфер содержит выходные данные
_F_TERM 0x0200 Файл является терминалом

 

Функции для работы с файлами.

 

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

Функция открывает файл, имя которого принимает в качестве параметра path, и связывает его с потоком. В случае успеха функция возвращает указатель на файловую переменную, в случае ошибки – NULL. Параметр mode задает режим открытия файла.

 

Режим Действие
«r» Открыть существующий файл для чтения (файл должен существовать на диске). Указатель чтения-записи устанавливается в начало файла.
«w» Открыть существующий (содержимое при открытии теряется) или создать новый файл для записи. Указатель чтения-записи устанавливается в начало файла, при закрытии размер файла усекается по размеру до текущей позиции указателя.
«a» Открыть существующий или создать новый файл для добавления (запись в конец файла). Указатель чтения-записи устанавливается в конец файла.
«r+» Открыть файл для чтения и записи. Указатель чтения-записи устанавливается в начало файла. При закрытии файла размер не усекается.
«w+» Создать или открыть файл для чтения и записи, если файл существует, он перезаписывается. Указатель чтения-записи устанавливается в начало файла. При закрытии файла размер усекается.
«a+» Создать или открыть файл для добавления для чтения и записи. Указатель чтения-записи устанавливается в конец файла. При закрытии файла размер не усекается.
«rb» Аналогично «r», бинарный режим
«wb» Аналогично «w», бинарный режим
«ab» Аналогично «a», бинарный режим
«r+b» Аналогично «r+», бинарный режим
«w+b» Аналогично «w+», бинарный режим
«a+b» Аналогично «a+», бинарный режим
«rt» Аналогично «r», текстовый режим
«wt» Аналогично «w», текстовый режим
«at» Аналогично «a», текстовый режим
«r+t» Аналогично «r+», текстовый режим
«w+t» Аналогично «w+», текстовый режим
«a+t» Аналогично «a+», текстовый режим

 

Если текстовый или бинарный режим не задан явно, он устанавливается по умолчанию в зависимости от значения внешней переменной _fmode.

Возвращаемый функцией указатель всегда следует проверять на равенство константе NULL (как и при использовании динамического распределения памяти).

 

FILE * freopen(const char * path, const char * mode, FILE * stream);

Функция закрывает поток stream и открывает файл, имя которого принимает в качестве параметра path, и связывает его с потоком. В случае успеха функция возвращает указатель на файловую переменную, в случае ошибки – NULL. Параметр mode задает режим открытия файла. Данная функция может быть использована для перенаправления стандартных потоков.

 

FILE * tmpfile(void);

Открывает временный файл с правами доступа «w+b», который можно закрывать, а можно и не закрывать – при завершении программа сама автоматически закроет его. В случае успеха функция возвращает указатель на файловую переменную, в случае ошибки – NULL.

 

int rmtmp(void);

Функция закрывает и удаляет все открытые временные файловые потоки. Возвращает число закрытых и удалённых файловых потоков.

 

int fflush(FILE * stream);

Функция выполняет передачу данных из внутреннего буфера файла stream на устройство. Функция возвращает 0, если операция прошла успешно, и EOF в случае ошибки. Данная операция необходима, чтобы предотвратить потерю данных в буфере в случае внезапного сбоя системы.

 

int flushall(void);

Функция выполняет передачу данных из внутренних буферов всех файлов и возвращает общее число входных и выходных потоков.

 

int unlink(const char* filename);

Функция удаляет файл filename, имя файла должно быть абсолютным. Файл, имеющий атрибут read-only, не может быть удалён данной функцией. Кроме того, не может быть удалён открытый файл (его нужно предварительно закрыть). В случае успеха, функция возвращает 0, в случае ошибки функция возвращает –1 и устанавливает значение переменной errno в одно из следующих значений: ENOENT – файл не существует, EACCES – нет прав доступа.

 

int remove(const char* filename);

Макрос, выполняющий вызов функции unlink(). Аналогичен функции unlink().

 

int rename(const char* oldname, const char* newname);

Функция переименовывает файл oldname в файл newname. В случае успеха функция возвращает 0, в случае ошибки функция возвращает –1 и устанавливает значение переменной errno в одно из следующих значений: ENOENT – файл не существует, EACCES – нет прав доступа, ENOTSAM – неверно задано устройство.

 

void setbuf(FILE * stream, char * buf);

Функция задает для файла stream область памяти, которая будет использоваться под буфер. Адрес начала буфера передается в качестве параметра buf, который должен быть указателем на блок памяти размером BUFSIZ (макрос, результат макрорасширения – 512). Если buf==NULL, то обмен данными будет небуферирован. По умолчанию для обычных файлов используется буфер размером 512 байтов, для стандартных потоков – 128 байтов.

 

int setvbuf(FILE * stream, char * buf, int type, size_t size);

Функция задает для файла stream область памяти, которая будет использоваться под буфер. Адрес начала буфера передается в качестве параметра buf, который должен быть указателем на блок памяти размером size (0<size<32K). Параметр type определяет способ буферизации и может иметь следующие значения, определенные как макросы.

 

Макрос Значение Способ буферизации
_IOFBF Полная буферизация, если buf==NULL, то функция сама выделяет буфер размером size
_IOLBF Построчная буферизация
_IONBF Буферизация отсутствует

 

void rewind(FILE * stream);

Функция устанавливает указатель чтения-записи в начало файла (потока) stream.

 

int fseek(FILE * stream, long offset, int whence);

Функция позиционирует указатель чтения-записи для потока stream на offset байтов от точки отсчёта, задаваемой параметром whence. Для задания точки отсчёта определены следующие макросы.

 

Макрос Значение Точка отсчёта
SEEK_SET Начало файла
SEEK_CUR Текущая позиция
SEEK_END Конец файла

 

В случае успеха функция возвращает 0, в случае ошибки – значение, отличное от 0.

 

long ftell(FILE * stream);

Функция возвращает в случае успеха смещение текущей позиции указателя чтения- записи для файла stream от начала файла, в случае ошибки -1L.

 

int fclose(FILE * stream);

Функция выполняет закрытие файла stream, при этом происходит освобождение буфера. Функция возвращает 0, если операция закрытия прошла успешно, и EOF в случае ошибки.

 

int fcloseall(void);

Функция выполняет закрытие всех открытых файлов и возвращает число закрытых файлов, если операция закрытия прошла успешно, и EOF в случае ошибки.

 

int feof(FILE * fp);

Макрос feof() выполняет проверку, достигнут ли конец файла (потока) fp, и возвращает 0, если конец файла не достигнут, или значение, отличное от 0, если при последней операции чтения из файла был достигнут конец файла.

 

int ferror(FILE * fp);

Макрос ferror() выполняет проверку, была ли ошибка ввода-вывода в файле fp, и возвращает 0, если ошибки не было, или значение, отличное от 0, если ошибка была. Если же следующая после ошибочной операция с файлом пройдет успешно, то функция возвратит 0 и сообщение об ошибке будет потеряно.

 

Функции потокового ввода-вывода можно разделить на 4 группы.

1. Функции посимвольного ввода-вывода – за одно обращение к файлу передаётся один символ.

2. Функции построчного ввода-вывода – за одно обращение передаётся строка.

3. Функции блочного ввода-вывода – за одно обращение передаётся блок информации (байтов), при работе с ними лучше открывать файлы в бинарном режиме.

4. Функции форматированного ввода-вывода – за одно обращение передаётся строка, формируемая по заданной строке формата, в которую могут быть подставлены значения переменных разных типов.

 

int getc(FILE * stream);

int putc(const int c, FILE * stream);

Макрос getc() производит ввод символа из потока stream. Макрос putc() производит вывод символа, код которого принимает в качестве аргумента c, в поток stream. Оба макроса в случае успеха возвращают код символа, в случае ошибки – EOF.

 

int fgetc(FILE * stream);

int fputc(int c, FILE * stream);

Функция fgetc() производит ввод символа из потока stream. Функция fputc() производит вывод символа, код которого принимает в качестве аргумента c, в поток stream. Обе функции в случае успеха возвращают код символа, в случае ошибки – EOF. Они аналогичны макросам getc() и putc().

 

char * fgets(char* s, int n, FILE * stream);

Функция fgets() производит ввод символов из потока stream в буфер, адрес которого принимает в качестве параметра s, пока не встретится символ перевода строки или пока не будет прочитано (n-1) символов. После последнего введенного символа функция помещает нулевой байт, либо преобразует символ перевода строки в нулевой байт. Функция в случае успеха возвращает s, в случае ошибки – NULL.

 

int fputs(const char * s, FILE * stream);

Функция fputs() производит вывод строки, адрес которой принимает в качестве параметра s, в поток stream. Функция в случае успеха возвращает неотрицательное значение, в случае ошибки – EOF.

 

size_t fread(void * ptr, size_t size, size_t n, FILE * stream);

size_t fwrite(const void * ptr, size_t size, size_t n, FILE * stream);

Функции fread() и fwrite() осуществляют чтение и запись соответственно блока данных в файл или из файла. Указатель ptr указывает на начало блока данных, n – число записей длиной size байтов, которые будут считаны или записаны, size – размер одной записи в байтах, stream – указатель на поток. В случае успеха функции возвращают число считанных или записанных записей, в случае ошибки – 0.

 

int fscanf(FILE * stream, const char * format, ...);

int fprintf(FILE * stream, const char * format, ...);

Функции fscanf() и fprintf() осуществляют форматированный ввод и вывод соответственно (аналогично функциям scanf() и printf()) в поток (из потока) stream.

 

int sscanf(const char * buffer, const char * format, ...);

int sprintf(char * buffer, const char * format, ...);

Функции sscanf() и sprintf() осуществляют форматированный ввод и вывод соответственно (аналогично функциям scanf() и printf()) в стороку (из строки) buffer.

В случае успеха функции fprintf() и sprintf() возвращают число выведенных символов, в случае ошибки – EOF. В случае успеха функции fscanf() и sscanf() возвращают число удачно введённых и распознанных полей, 0 – если ни одного поля не распознано, в случае ошибки – EOF.

 

Стандартные потоки.

При запуске программы системой создаются структуры типа FILE, связанные со стандартными потоками:

stdin – стандартный поток ввода (связан с клавиатурой);

stdout – стандартный поток вывода (связан с монитором);

stderr – стандартный поток ошибок (связан с монитором);

stdaux – стандартный поток дополнительного устройства (связан с портом COM1);

stdprn – стандартный поток принтера (связан с принтером).

Два последние потока являются дополнительными, данные устройства могут и не поддерживаться ОС или не входить в состав ПК.

Эти имена описаны в файле stdio.h в виде макросов, результатом макрорасширения и будет адрес структуры типа FILE. С помощью данных потоков осуществляется ввод-вывод на стандартные устройства компьютера.

При завершении работы программы данные потоки закрываются автоматически.

Предопределённые префиксы файлов стандартного ввода-вывода приведены в таблице ниже.

 

Префикс Имя устройства Имя потока
00h CON stdin
01h CON stdout
02h CON stderr
03h AUX stdaux
04h PRN stdprn

 

Функции для работы со стандартными потоками.

Для функций ввода окончание ввода осуществляется нажатием клавиши ENTER.

 

Функции printf() и scanf() были рассмотрены на практических занятиях ранее.

 

int getchar(void);

int putchar(const int c);

Макрос getchar() производит ввод символа из стандартного потока ввода. Макрос putchar() производит вывод символа, код которого принимает в качестве аргумента, в стандартный поток вывода. Оба макроса в случае успеха возвращают код символа, в случае ошибки – EOF.

 

char * gets(char * s);

Функция gets() производит ввод строки из стандартного потока ввода в буфер, адрес начала которого принимает в качестве параметра. Функция в случае успеха возвращает s, в случае ошибки – NULL.

 

int puts(const char * s);

Функция puts() производит вывод строки, адрес которой принимает в качестве параметра, в стандартный поток вывода. Функция в случае успеха возвращает последний записанный символ, в случае ошибки – EOF.

 

void perror(const char * s);

Функция выводит в стандартный поток ошибок stderr строку, адрес которой принимает в качестве параметра.

 

– Конец работы –

Эта тема принадлежит разделу:

Лекция 29-30

На сайте allrefs.net читайте: Лекция 29-30.

Если Вам нужно дополнительный материал на эту тему, или Вы не нашли то, что искали, рекомендуем воспользоваться поиском по нашей базе работ: Лекция 29-30

Что будем делать с полученным материалом:

Если этот материал оказался полезным ля Вас, Вы можете сохранить его на свою страничку в социальных сетях:

Все темы данного раздела:

Эта работа не имеет других тем.

Хотите получать на электронную почту самые свежие новости?
Education Insider Sample
Подпишитесь на Нашу рассылку
Наша политика приватности обеспечивает 100% безопасность и анонимность Ваших E-Mail
Реклама
Соответствующий теме материал
  • Похожее
  • Популярное
  • Облако тегов
  • Здесь
  • Временно
  • Пусто
Теги