Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛАБ_ПРОГР.doc
Скачиваний:
8
Добавлен:
12.11.2019
Размер:
1.67 Mб
Скачать
    1. Перенаправление потока

Указатели стандартных потоков stdin, stdout, stderr, stdaux, stdprn являются константами, поэтому им нельзя присваивать новые значения указателя потока. Однако любой из этих потоков можно с помощью функции freopen() переадресовать на новое устройство или в другой поток, связанный с файлом на диске, например:

freopen(“file1.dat”,”w”,stdout);

Прототип функции freopen()

FILE *freopen (const char *имя_файла, const char *режим, FILE *поток);

Этот оператор закрывает поток для стандартного вывода и переназначает stdout файлу file1.dat.

Пример. Данная программа использует freopen() для перенаправления потока stdout в текстовый файл file1.msg. Здесь первый printf() выводит сообщение на экран, а второй printf() записывает сообщение в файл file1.msg, расположенный на диске.

#include <stdio.h>

#include <stdlib.h>

int main (void)

{

FILE *fp;

printf(“Это сообщение выводится на дисплей”);

if ((fp = freopen(“file1.msg”, “w”, stdout)) = = NULL) {

printf(“Не могу открыть файл”);

exit(1);

}

printf(“Это сообщение выводится в файл file1.msg”);

fclose(fp);

return 0;

}

    1. Чтение из потока и запись в поток

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

Классификация функций чтения и записи по типу объекта, над которым выполняется операция, и разновидности потока приведены в таблице 2.

Операция чтения и записи для потока начинается всегда с текущей позиции потока, определяемой указателем положения в файле. Начальное положение указателя положения в файле устанавливается при открытии потока и может указывать на начало или конец потока в зависимости от того, с каким режимом доступа открыт поток (режимы “r” и “w” устанавливают поток на начало, а режим “a” на конец). После выполнения операции чтения или записи указатель положения в файле изменяется для того, чтобы отразить новую текущую позицию потока. Например, если из потока был прочитан один символ, указатель положения в файле увеличивается на единицу, чтобы следующая операция чтения начиналась с первого байта после прочитанного.

Таблица 2 – Классификация функций чтения и записи потока

Объект операции

Операция ввода-вывода

Чтение

Запись

из потока stdin

из любого потока

из строки Си

в поток stdout

в любой поток

в строку Си

Последователь-ность байтов

fread()

fwrite()

Отдельный символ

getchar()

fgetchar()

putchar()

fputchar()

Данное типа int

getw()

putw()

Строка

gets()

fgets()

puts()

fputs()

Форматирован-ные данные

scanf()

fscanf()

sscanf()

printf()

fprintf()

sprintf()

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

ftell(), fgetpos() – получают текущую позицию указателя положения в файле;

fseek(), fsetpos() – устанавливают текущую позицию указателя;

rewind() – позиционирует указатель на начало потока.

Функция

long ftell (FILE *fp);

возвращает текущее значение указателя позиции в файле для указанного потока. Это значение представляет собой количество байт, на которое указатель отстоит от начала файла. В случае ошибки ftell() возвращает значение 1L.

Пример.

long i;

if ((I = ftell(fp) = = 1L) printf(“Ошибка”);

Функция

int fseek (FILE *fp, long число_байт, int начало);

устанавливает указатель положения в файле, связанном с fp, в соответствии со значениями число_байт и начало. Здесь: число_байт – это длинное целое, содержащее число байт от параметра начало до позиции указателя; начало – это одно из следующих макроопределений, установленных в stdio.h:

Имя Значение Позиция

SEEK_SET 0 Начало файла

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

SEEK_END 2 Конец файла

В случае успеха функция fseek() возвращает значение 0, в случае неудачи возвращает ненулевое значение.

П р и м е р ы использования функции fseek():

FILE *fp;

long n;

. . .

fseek(fp, 0L, SEEK_SET); /* позиционирование на начало потока */

fseek(fp, 0L, SEEK_END); /* позиционирование на конец потока */

fseek(fp, nL, SEEK_SET); /* позиционирование на n байт от начала потока */

fseek(fp, nL, SEEK_CUR); /* позиционирование на n байт от текущей позиции */

fseek(fp, nL, 1); /* позиционирование на n байт до текущей позиции */

fseek(fp, , nL, 2); /* позиционирует на n байт до конца потока */

fseek(fp, , nL, 2); /* указатель может быть позиционирован за конец потока */

fseek(fp, -nL, 0); /* Ошибка. Попытка установить указатель перед началом */

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

fseek(fp, 0L, SEEK_SET);

Имеет прототип

void rewind (FILE *fp);

Функции fgetpos() и fsetpos() обычно используются в паре. Функция fgetpos() хранит текущее значение указателя положения в файле, связанном с указателем fp, в некоторой переменной, на которую указывает номер_позиции. Прототип этой функции:

int *fgetpos (FILE *fp, fpos_t номер_позиции);

Функция fsetpos() устанавливает указатель положения в файле, связанном с потоком fp, в позицию, указанную параметром номер_позиции. Прототип этой функции:

int fsetpos (FILE *fp, const fops_t *номер_позиции);

Тип fops_t определен в stdio.h и соответствует типу long int.

В случае случае успешного завершения функции fgetpos() и fsetpos() возвращают значение 0 и при неудаче возвращается ненулевое значение.

Приведенная ниже функция читает группу байтов с использованием fgetpos() и fsetpos(). Позиция указателя положения в файле не меняется.

# include <stdio.h> /* требуется для объявления функции */

long read_bytes (FILE *fp, long n, char *save)

{

long num, /* число прочитанных байт */

pos; /* текущая позиция указателя положения */

num = 1L;

if (fgetpos(fp, &pos) = = 0) /* сохранить текущую позицию указателя */

num = fread(save, 1, num, fp); /* прочитать n байт */

fsetpos(fp, &pos); /* восстановить положение указателя положения */

return num;

}

Если поток открывается для добавления (режим доступа “a”, “a+” и т. д.) операции записи относятся к концу потока, хотя указатель положения может быть переустановлен. Это предохраняет данные в файле от затирания.

Нельзя использовать функции определения и установки указателя положения в файле для потока, представляющего устройство. Использование функций ftell(), fseek(), rewind(), fgetpos() и fsetpos() с любым из стандартных потоков приводит к неопределенным результатам.

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