ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 13.12.2020
Просмотров: 4288
Скачиваний: 28
Часть III. Стандартная библиотека языка программирования C
346
Функция
fseek
имеет следующий прототип:
int fseek(FILE* stream, long offset, int mode);
Эта функция сдвигает индикатор позиции файла на
offset
бай-
тов. В случае успешного завершения функция возвращает
0
, в
противном случае — ненулевое значение. Параметр
mode
указы-
вает на режим сдвига и может принимать значения, определен-
ные следующими символическими константами:
SEEK_SET
— смещение от начала файла;
SEEK_CUR
— смещение от текущей позиции;
SEEK_END
— смещение от конца файла.
При работе с текстовым потоком должны использоваться только
следующие комбинации значений параметров:
mode = SEEK_SET
, а
offset
равно 0 или значению, возвращен-
ному функцией
ftell
;
mode = SEEK_CUR
и
offset = 0
;
mode = SEEK_END
и
offset = 0
.
Функция
fsetpos
имеет следующий прототип:
int fsetpos(FILE* stream, const fops_t *pos);
Эта функция устанавливает индикатор позиции файла
stream
в
позицию, на которую указывает параметр
pos
. Индикатор конца
файла сбрасывается. В случае успеха функция возвращает
0
, а в
случае неудачи — ненулевое значение и устанавливает перемен-
ную
errno
.
Функция
ftell
имеет следующий прототип:
long ftell(FILE* stream);
Эта функция в случае успешного завершения возвращает теку-
щую позицию файла
stream
, а в случае неудачи — возвращает
значение -
1L
и устанавливает значение переменной
errno
. Для
бинарного потока позиция равна смещению в байтах от начала
файла, а в случае текстового потока — значению, которое может
использоваться функцией
fseek
.
Глава 30. Функции для работы с файлами <stdio.h>
347
Функция
fgetpos
имеет следующий прототип:
int fgetpos(FILE* stream, fops_t* pos);
Эта функция записывает текущую позицию файла
stream
по ад-
ресу
pos
. В случае успеха функция возвращает
0
, а в случае не-
удачи — ненулевое значение и устанавливает значение перемен-
ной
errno
.
30.8. Блочный ввод/вывод
Блоком
называется область оперативной памяти, содержимое ко-
торой записывается в файл. Ввод/вывод блоками используется
главным образом при работе с бинарными потоками.
Для записи блока в файл используется функция
fwrite
, которая
имеет следующий прототип:
size_t fwrite(const void* ptr,
size_t size, size_t nitems, FILE* stream);
Эта функция записывает содержимое блока памяти, на который
указывает параметр
ptr
, в файл
stream
. Длина записываемого
блока определяется как произведение
size*nitems
. Функция воз-
вращает количество записанных единиц памяти. В случае удачи
это число должно быть равно
nitems
. В случае неудачи функция
fwrite
устанавливает индикатор ошибки.
Для чтения блока из файла используется функция
fread
, которая
имеет следующий прототип:
size_t fread(const void* ptr,
size_t size, size_t nitems, FILE* stream);
Параметры этой функции имеют тот же смысл, что и параметры
функции
fwrite
. Функция возвращает количество прочитанных
единиц памяти. В случае удачи это число должно быть равно
nitems
. В случае неудачи функция
fwrite
устанавливает индика-
тор ошибки или индикатор конца файла.
В случае ошибки состояние индикатора позиции после работы
функций
fwrite
и
fread
не определено. Иначе индикатор позиции
сдвигается на количество записанных и прочитанных байтов.
Часть III. Стандартная библиотека языка программирования C
348
В листинге 30.1 приведена программа, которая создает бинарный
файл.
Листинг 30.1. Запись блоков в файл
#include <stdio.h>
struct emp
{
int code;
char name[20];
double salary;
};
int main()
{
int i, n;
FILE* out; /* выходной поток */
struct emp s; /* для записей файла */
s.salary = 0.0; /* для обработки плавающих чисел */
/* открываем выходной поток в бинарном режиме */
out = fopen("employee.bin", "wb");
printf("Input a number of records to write: ");
scanf("%d", &n);
if (n < 0)
return 0;
printf("Input code, name and salary.\n");
for (i = 0; i < n; ++i)
{
printf("%d> ", i + 1);
/* вводим запись с консоли */
scanf("%d%s%lf", &s.code, &s.name, &s.salary);
/* пишем запись в файл */
fwrite(&s, sizeof(struct emp), 1, out);
}
/* закрываем выходной поток */
fclose(out);
return 0;
}
Глава 30. Функции для работы с файлами <stdio.h>
349
В листинге 30.2 приведена программа, которая выполняет чтение
записей из созданного бинарного файла.
Листинг 30.2. Чтение блоков из файла
#include <stdio.h>
struct emp
{
int code;
char name[20];
double salary;
};
int main()
{
FILE* in; /* выходной поток */
struct emp s; /* для записей файла */
s.salary = 0.0; /* для обработки плавающих чисел */
long i; /* номер записи */
/* открываем входной поток в бинарном режиме */
if(!(in = fopen("employee.bin", "rb")))
{
printf("Open file failed.\n");
return 0;
}
printf("Input negative index to exit.\n");
for (;;)
{
/* читаем индекс */
printf("Input an index: ");
scanf("%d", &i);
if (i < 0)
break;
/* устанавливает указатель на нужную запись */
fseek(in, i*sizeof(struct emp), SEEK_SET);
/* читаем запись из файла */
if(!fread(&s, sizeof(struct emp), 1, in))
Часть III. Стандартная библиотека языка программирования C
350
{
printf("The wrong index.\n");
continue;
}
/* выводим запись на консоль */
printf("\tcode = %d name = %s sal = %f\n",
s.code, s.name, s.salary);
}
/* закрываем входной поток */
fclose(in);
return 0;
}
30.9. Ввод/вывод символов
Для записи и чтения символов (байтов) из файла используются
функции
fputc
,
putc
,
fgetc
и
getc
.
Функция
fputc
имеет следующий прототип:
int fputc(int c, FILE* stream);
Эта функция записывает символ, заданный параметром
c
, в поток
stream
и продвигает индикатор позиции на следующий символ.
В случае успеха функция возвращает символ
c
, а в случае неуда-
чи — значение
EOF
и устанавливает индикатор ошибки.
Функция
putc
имеет следующий прототип:
int putc(int c, FILE* stream);
Эта функция работает так же, как и функция
fputc
, но может
быть реализована как макрокоманда.
Пример использования функции
putc
приведен в листинге 30.3.
Листинг 30.3. Запись символов в файл
#include <stdio.h>
int main()