Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Название:Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:0101
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание
Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
550 глава 13
Предположим, например, что вам нужна функция, которая читает все символы до следующего двоеточия, не включая его. Вы можете применить getchar() или getc() для чтения символов до двоеточия и затем вызвать ungetc(), чтобы вернугь двоеточие обратно во входной поток. Стандарт ANSI С гарантирует только одно заталкивание за один раз. Если реализация разрешает заталкивать сразу несколько символов в строке, функции ввода прочитают их в порядке, обратном заталкиванию.
Рис. 13.2. Функция ungetc 0
ФУНКЦИЯ int fflush()
Прототип fflush() выглядит так:
int fflush(FILE *fр);
Вызов функции fflush() приводит к тому, что любые незаписанные данные в буфере вывода отправляются в выходной файл, идентифицируемый с помощью fp. Этот процесс называется сбросом буфера. Если fp — нулевой указатель, то сбрасываются все буферы вывода. Результат использования функции fflush() на входном потоке не определен. Ее можно применять с потоком обновления (для любого режима чтения- записи), при условии, что самая последняя операция, использующая поток, не была операцией ввода.
ФУНКЦИЯ int setvbuf()
Прототип setvbuf() имеет следующий вид:
int setvbuf(FILE * restrict fp, char * restrict buf, int mode, size_t size);
Функция setvbuf() устанавливает альтернативный буфер, предназначенный для применения стандартными функциями ввода-вывода. Она вызывается после того, как файл был открыт, и перед выполнением любой другой операции на потоке данных. Указатель fp идентифицирует поток, a buf указывает на используемое хранилище. Значение buf, не равное NULL, говорит о том, что буфер вы создаете самостоятельно. Например, вы могли бы объявить массив из 1024 элементов char и передать адрес этого массива. Однако если в качестве значения buf указывается NULL, то функция сама выделит память под буфер. Аргумент size сообщает setvbuf() размер этого массива, (size t — это производный целочисленный тип, который рассматривался в главе 5.) Для mode доступны следующие варианты: I0FBF означает полную буферизацию (буфер сбрасывается, когда полон), I0LBF — построчную буферизацию (буфер
Файловый ввод-вывод 551
сбрасывается, когда полон или когда в него записан символ новой строки) и IONBF — отсутствие буферизации. Функция возвращает ноль при успешном завершении и ненулевое значение в противном случае.
Предположим, что у вас есть программа, которая работает с сохраненными объектами данных, имеющими размер, скажем, по 3 000 байтов каждый. Вы могли бы с помощью setvbuf() создать буфер, размер которого кратен размеру объекта данных.
ДВОИЧНЫЙ ввод-вывод: fread() И fwrite()
Следующими в списке идут функции fread() и fwrite(), но сначала мы затронем некоторые основы. Стандартные функции ввода-вывода, которые вы применяли до сих пор, были ориентированы на текст, работая с символами и строками. А что, если в файле нужно сохранить числовые данные? Действительно, можно воспользоваться функцией fprintf() и форматом %f, чтобы сохранить значение с плавающей запятой, но тогда оно сохранится как последовательность символов. Например, код
double num = 1./3 .;
fprintf(fp,"%f", num);
сохраняет num в виде последовательности из восьми символов: 0.333333.
Применение спецификатора %. 2f позволяет сохранить его как последовательность из четырех символов: 0.33. Использование спецификатора %.12f дает возможность сохранить его в виде 14 символов: 0.333333333333. Смена спецификаторов приводит к изменению размера пространства, необходимого для значения. После того, как значение num было сохранено как 0.33, нет никакой возможности вернуться к полной точности значения при его чтении из файла. В общем случае функция fprintf() преобразует числовые значения в символьные данные, возможно изменяя значения.
Наиболее точный и единообразный способ сохранения числа предусматривает использование того же самого набора битов, что и компьютер. Таким образом, значение double должно быть сохранено в области с размером как у типа double. Когда данные хранятся в файле в представлении, которое применяется в программе, мы говорим, что данные сохранены в двоичтй форме. Никакие преобразования из числовых форм в последовательности символов не производятся. Для стандартного ввода-вывода такую услулу предлагают функции fread() и fwrite(), работа которых иллюстрируется на рис. 13.3.
В действительности, как вы помните, все данные хранятся в двоичной форме. Даже символы хранятся с использованием двоичного представления их кодов. Однако если все данные в файле интерпретируются как коды символов, мы говорим, что файл содержит текстовые данные. Если некоторые или все данные интерпретируются как числовые данные в двоичной форме, мы говорим, что файл содержит двоичные данные. (Кроме того, двоичными также являются файлы, в которых данные представляют собой команды на машинном языке.)
Применение терминов двоичный и текстовый может привести к путанице. Стандарт ANSI С распознает два режима открытия файлов: двоичный и текстовый. Многие операционные системы распознают два файловых формата: двоичный и текстовый. Все эти характеристики связаны, но не идентичны. Вы можете открывать файл текстового формата в двоичном режиме. Вы можете сохранять текст в файле двоичного формата. Вы можете использовать функцию getc() для копирования файлов, содержащих двоичные данные. Однако для сохранения двоичных данных в файле двоичного формата вы обычно будете применять двоичный режим. Аналогично, чаще всего работа с текстовыми данными в текстовых файлах производится при их открытии в текстовом режиме. (Файлы, генерируемые текстовыми процессорами, как правило, являются двоичными, поскольку они содержат много нетекстовой информации, которая описывает шрифты и форматирование.)
552 глава 13
Рис. 13.3. Двоичный и текстовый вывод
ФУНКЦИЯ size_t fwrite()
Ниже показан прототип функции fwrite():
size_t fwrite(const void * restrict ptr, size_t size, size_t nmemb,
FILE * restrict fp);
Функция fwrite() записывает двоичные данные в файл. Тип size_t определен в терминах стандартных типов С. Это тип, возвращаемый операцией sizeof. Обычно им является unsigned int, но реализации могут выбирать другой тип. Указатель ptr — это адрес порции данных, предназначенной для записи. Аргумент size представляет размер в байтах порции данных, подлежащих записи, a nmemb — количество таких порций. Как обычно, fp идентифицирует файл, в который должна производиться запись. Например, чтобы сохранить объект данных (такой как массив) размером 256 байтов, можно поступить так:
char buffer[256];
fwrite (buffer, 256, 1, fp);
Этот вызов fwrite() записывает одну порцию даниых размером 256 байтов из буфера в файл. Чтобы сохранить, скажем, массив из 10 элементов double, понадобятся следующие операторы:
Читать дальшеИнтервал:
Закладка: