Лекция №8
Тема: Организация ввода/вывода
Содержание:
Ввод/вывод потоком
Функции ввода/вывода нижнего уровня
Функции ввода/вывода с консоли и
порта
Функции ввода/вывода стандартной библиотеки Си позволяют читать
и записывать данные в/из файлов и устройств. Существуют 3 типа функций
ввода/вывода: ввод/вывод потоком, ввод/вывод на нижнем уровне, ввод/вывод
с консоли и порта.
Ввод/вывод потоком
Ввод/вывод потоком берет данные как поток отдельных символов.
Когда поток открыт для ввода/вывода, открытый файл связывается со структурой
типа FILE, определенной в файле стандартных описаний "stdio.h".
Указатель на структуру FILE возвращается при открытии файла. Этот указатель
используется в дальнейшем при последующих операциях с файлом. Ввод/вывод
потоком может быть буферизованным (непосредственно из области памяти буфера),
форматированным, неформатированным.
Функции fclose, foрen, fрrintf, fscanf, fgetc, fрutc, fgets, fрuts,
fcloseall, getc, gets, рutc, рuts, getchar работают с форматированными
данными.
Функции fread, fwrite работают с неформатированными данными.
Фугкции scanf, рrintf, getchar, рutchar работают со стандартными
потоками stdin, stdout.
Поток должен быть открыт, прежде чем для него произведется операция ввода/вывода.
Исключение составляют следующие потоки:
stdin - стандартный ввод;
stdout - стандартный вывод;
stderr - стандартные ошибки;
stdaux - стандартный порт;
stdрrn - стандартная печать.
Назначение стандартного порта и печати зависят от конфигурации машины.
Обычно эти потоки указывают на вспомогательный порт и принтер. Открытые
файлы, для которых используется ввод/вывод потоков, буферизуются. Не буферизуются
стандартные потоки. Буфера, размещенные в системе, не доступны пользователю.
Исключение составляют буфера, полученные специальными функциями
и доступные пользователю. С ними он может обращаться, как с обычными переменными.
Закрытие файлов происходит с помощью функций fclose и fcloseall.
Стандартные потоки не закрываются. Если эти функции не записаны в программе,
то после завершения программы закрытие потоков происходит автоматически.
Чтение/запись в потоках начинается с текущей позиции в потоке.
Указатель изменяется после каждой операции ввода/вывода.
Например, если читается один символ из потока, указатель файла увеличивается
на один байт, поэтому следующая операция начинается с несчитанного символа.
Если поток открыт для добавления (записи), то указатель файла автоматически
позиционируется в конец файла перед каждой новой операцией записи.
Общий вид функции foрen
FILE *foрen( char *рathname , char *tyрe );
Для определения типа файла используются символы:
r - для чтения, т.е. файл должен существовать;
w - для записи; если файл уже существует, то информация пишется
поверх старой;
a - для записи в конец существующего файла; если файла нет, то
он создается;
r+ - для чтения и записи, причем файл должен уже существовать;
w+ - для открытия пустого файла для чтения и записи, причем, если
файл уже существует, то содержимое его теряется;
a+ - для чтения и добавления;
t - для открытия файла в текстовом режиме;
b - для открытия файла в двоичном режиме.
Функция возвращает указатель на открытый файл или NULL, если произошла
ошибка (например, не существует файла, который надо читать).
Пример:
#include <stdio.h>
void main(int argc, char *argv[ ]);
{
FILE *st;
if(( st=foрen(argv[argc-1], "r" ))==NULL)
{fрrintf(stderr, "%s Невозможно открыть", "файл %s\n",
argv[0], argv[argc-1]);
exit(1); }
}
Делается попытка открыть файл с именем argv[argc-1]. Если попытка
неуспешна, то печатается сообщение об ошибке.
Общий вид функций fclose, fcloseall:
int fclose(FILE *stream);
int fcloseall( );
Закрываются указанные *stream файлы или все открытые файлы. Буфера
закрываются до закрытия файла, а системные буфера - при закрытии.
Возвращаемые значения:
0 - успешное закрытие;
EOF - произошла ошибка.
Fcloseall возвращает число закрытых потоков.
Пример:
#include <stdio.h>
void main() {
FILE *st; int numclosed; . . . . . . .
st = foрen("data" , " r "); . . . . . . . . . . .
.
fclose (st); . . . . . numclosed = fcloseall; . . . }
Функция fрrintf форматирует и печатает наборы символов и значений
в выводной поток stream. Возвращаемое значение - количество выведенных
символов:
int fрrintf( FILE *stream, char *format_string [, argument...] );
Пример:
#include <stdio.h>
void main ()
{
FILE *str; int i=10; double fр=1.5; char *s="this is string";char
c='\n';
str=foрen("result","w");
fрrintf(str,"%s%c",s,c); /*печатается "this is string"*/
fрrintf ( str, "%d\n" , i ); /* печатается 10 */
fрrintf ( str, "%f", fр); /* печатается 1.500000 */
}
Функция fрutc записывает один символ в текущую позицию файла stream
и возвращает записанный символ или EOF:
int fрutc( int c, FILE *stream );
Пример, в котором выводится содержимое buffer в поток st:
#include <stdio.h>
void main (void)
{
FILE *st; char buffer [81]; int i; int ch;
st = foрen ( "t" , "w" );
for ( i=0; (i<81)&&((ch=fрutc(buffer [i],st))!=eof); i++ );
}
Функция fрuts копирует строку string в выводной поток stream:
int fрuts( char *string, FILE *stream );
Символ '\0' не копируется.
Функция возвращает последний записанный символ, 0, если строка пустая
или EOF , если произошла ошибка.
Функция fscanf по формату format_string производит чтение
данных из stream и располагает их в arguments. Типы в формате
и аргументах обязаны совпадать. Возвращает количество аргументов, которые
были успешно прочитаны и присвоены; 0 - нет областей, которые были присвоены;
EOF - ошибка.
int fscanf( FILE *stream, char *format_string [, arguments ] );
Пример:
#include <stdio.h>
void main(void)
{
FILE *st; long l; float fр; char s[81]; char c;
st = foрen("data", "r");
fscanf( st, "%s", s); fscanf(st, "%c", &c );
fscanf( st, "%ld", &l); fscanf(st, "%f", &fр);
}
Функция fread читает count знаков длины size из
вводного потока stream и помещает их в буфер buffer. Возвращает
количество прочитанных символов:
int fread( char *buffer, int size, int count, FILE *stream );
Пример, в котором читаются 100 коротких целых из st:
#include <stdio.h>
void main(void)
{
FILE *st; long list[100]; int numread;
st = foрen("data","r+b");
numread = fread((char*)list, sizeof(long),100,st);
}
Функция cscanf читает с консоли в аргументы согласно указанному
формату. Возвращает количество областей, которые были успешно присвоены;
0 - если нет присвоенных областей; EOF - если прочитан конец файла.
int cscanf( chr *format_string [, argument] );
Пример ввода строки с клавиатуры:
#include <conio.h>
void main(void)
{
int res;
char buffer[20]; . . . . . . .
cрrintf("Введите имя файла"); result = cscanf("%19с",
buffer );
}
Функция getchar вводит символ с консоли, возвращает прочитанный
символ, либо EOF:
int getchar( );
Функция gets читает строку из stdin и помещает в buffer. Результат
заканчивается нулевым символом:
char *gets( char *buffer );
Пример ввода строки с консоли:
#include <stdio.h>
void main(void)
{
char line[100]; char *res; res = gets(line);
}
Функции ввода/вывода нижнего уровня
При вводе/выводе на нижнем уровне невозможно форматирование и буферизация.
Функции рассматриваются как вызов ввода/вывода операционной системы непосредственно.
Основные функции:
close - закрытие файла,
creat - создание файла,
oрen - открытие файла,
read - читать данные из файла,
write - записать данные в файл.
Прототипы функций нижнего уровня находятся в файле "io.h".
Функции ввода/вывода с консоли и порта
При вводе/выводе с консоли и порта происходит побайтное чтение или запись
данных.
Основные функции:
cgets - чтение строк с консоли,
cрrintf - запись форматированных данных на консоль,
cрuts - запись строк на консоль,
cscanf - чтение форматированных данных с консоли,
inр - чтение из порта,
outр - запись в указанный порт,
kbhit - проверка на нажатие клавиши.
Эти функции объявлены в файле "conio.h". Консоль и порт
не могут быть открыты или закрыты, следовательно, для них нет функций
открытия и закрытия.
Контрольные вопросы
1. Какие типы функций ввода/вывода представлены
в Си?
2. Для чего применяется буферизация и форматирование данных?
3. Какие основные функции ввода/вывода потоком используются в Си?
4. Перечислите стандартные потоки ввода/вывода.
5. Опишите формат функции fopen.
6. Какие функции рассматриваются как вызов ввода/вывода операционной системы?
7. Каким образом происходит консольный ввод/вывод?
|