Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lab_4.doc
Скачиваний:
1
Добавлен:
14.11.2019
Размер:
269.31 Кб
Скачать

Ввод/вывод потоком

Ввод/вывод потоком берет данные как поток отдельных символов. Когда поток открыт для ввода/вывода, открытый файл связывается со структурой типа 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, printf, getchar, putchar работают со стандартными потоками stdin, stdout.

Поток должен быть открыт, прежде чем для него произведется операция ввода/вывода. Исключение составляют следующие потоки:

stdin - стандартный ввод;

stdout - стандартный вывод;

stderr - стандартные ошибки;

stdaux - стандартный порт;

stdрrn - стандартная печать.

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

Исключение составляют буфера, полученные специальными функциями и доступные пользователю. С ними он может обращаться, как с обычными переменными.

Закрытие файлов происходит с помощью функций fclose и fcloseall. Стандартные потоки не закрываются. Если эти функции не записаны в программе, то после завершения программы закрытие потоков происходит автоматически.

Чтение/запись в потоках начинается с текущей позиции в потоке.

Указатель изменяется после каждой операции ввода/вывода. Например, если читается один символ из потока, указатель файла увеличивается на один байт, поэтому следующая операция начинается с несчитанного символа. Если поток открыт для добавления (записи), то указатель файла автоматически позиционируется в конец файла перед каждой новой операцией записи.

Общий вид функции foрen

FILE *foрen( char *pathname , char *type );

Для определения типа файла используются символы:

r - для чтения, т.е. файл должен существовать;

w - для записи; если файл уже существует, то информация пишется поверх старой;

a - для записи в конец существующего файла; если файла нет, то он создается;

r+ - для чтения и записи, причем файл должен уже существовать;

w+ - для открытия пустого файла для чтения и записи, причем, если файл уже существует, то содержимое его теряется;

a+ - для чтения и добавления;

t - для открытия файла в текстовом режиме;

b - для открытия файла в двоичном режиме.

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

Пример:

#include <stdio.h>

void main()

{

char *filename=“data”;

FILE *st;

if(( st=foрen(filename, “r” ))==NULL)

{

рrintf(“ Невозможно открыть файл %s\n”, filename);

exit(1);

}

}

Делается попытка открыть файл с именем filename. Если попытка неуспешна, то печатается сообщение об ошибке.

Общий вид функций 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 *st;

int i=10;

double fр=1.5;

char *s="this is string";

char c='\n';

st=foрen(“result”,”w”);

fрrintf(st,”%s%c”,s,c); // печатается "this is string"

fрrintf(st, “%d\n” , i ); // печатается 10

fрrintf(st, “%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()

{

FILE *st;

long i;

float fр;

char s[81];

char c;

st = foрen(“data”, “r”);

fscanf(st, “%s”, s);

fscanf(st, “%c”, &c );

fscanf(st, “%d”, &i);

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()

{

FILE *st;

int list[100];

int numread;

st = foрen(“data”,”r+b”);

numread = fread((char*)list, sizeof(int), 100, st);

}

Функция fwrite записывает count знаков длины size в вводной поток stream из буфера buffer. Возвращает количество прочитанных символов:

int fwrite(char *buffer, int size, int count, FILE *stream );

Пример, в котором записывается строка str длиной strlen(str) в st:

#include <stdio.h>

#include <string.h>

void main()

{

FILE *st;

char str[]="This is string";

int numread;

st = foрen(“data”,”w+b”);

numread = fwrite(str, sizeof(char), strlen(str)+1, st);

}

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

int ftell(FILE *stream);

Изменить позицию указателя можно функцией fseek:

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

Эта функция задает сдвиг на число байтов offset относительно точки отсчета, определяемой параметром whence. Параметр whence может принимать значения:

Константа

whence

Точка отсчета

SEEK_SET

0

Начало файла

SEEK_CUR

1

Текущая позиция

SEEK_END

2

Конец файла

Если задано значение whence = 1, то offset может быть положительным (сдвиг вперед) или отрицательным (сдвиг назад).

Функция fseek(st, 0L, 0) перемещает указатель на начало файла st (позиция 0).

Возможность перемещать указатель особенно полезна в файлах, которые состоят из однородных записей одинакового размера. Например, если в файле записаны только действительные числа типа double, то для того, чтобы прочитать i-oe число, достаточно выполнить операторы:

fseek(st, sizeof(double)*(i-1), 0);

fread(&a, sizeof(double), 1, st);

Таким образом, можно читать любые записи в любой последовательности.

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