Именованные файлы
Чтобы осуществлять операции ввода/вывода с потоками, отличными от stdin, stdout и stderr, необходимо предварительно открыть их. Это можно проделать с помощью стандартной библиотечной функции fopen(). Получив в качестве аргумента маршрутное имя файла (то есть имя, под которым файл зарегистрирован в файловой системе ОС UNIX), функция fopen() организует поток, ассоциированный с этим файлом, и возвращает указатель на структуру типа FILE. Указатель впоследствии будет передаваться функциям, выполняющим запись и чтение.
Тип FILE определен во включаемом файле <stdio.h>. Чтобы открыть поток, в Вашей программе должна быть соответствущая директива #include и описание вида
FILE *fin;
Описание говорит о том, что fin является указателем на структуру типа FILE. Чтобы связать конкретный файл с таким указателем, то есть открыть файл, ассоциировать с ним поток и поместить в адресуемую указателем структуру информацию об этом потоке, нужно включить в программу оператор, подобный следующему:
fin = fopen ("filename", "r");
где filename - это маршрутное имя открываемого файла. "r" означает, что файл открывается на чтение. Этот аргумент называется обычно режимом доступа к файлу. Как можно догадаться, имеются режимы чтения, записи, а также одновременно чтения и записи. Так как попытка открыть файл может завершиться неудачей, вызов функции fopen(), как правило, включают в условный оператор. Пример:
if ((fin = fopen ("filename", "r")) == NULL) (void) fprintf (stderr, "%s: Неудача при открытии файла %s\n",argv[0],"filename");
Здесь используется тот факт, что функция fopen() возвращает NULL в случае, если указанный файл не удается открыть.
Если файл удалось открыть, в последующих операциях ввода/вывода для ссылки на этот файл используется указатель fin. Пример:
int c; c = getc (fin);
В этом примере макрос getc() считывает из потока один символ и помещает его в целую переменную c. Хотя из потока считываются символы, переменная c описана как целая, поскольку макрос getc() возвращает целое. Чтение символа часто включается в какую-либо управляющую конструкцию, например так:
while ((c = getc (fin)) != EOF) . . .
Здесь символы будут считываться до тех пор, пока не будет достигнут конец файла. Константы EOF, NULL, а также макрос getc()
определены в <stdio.h>. getc()
и другие функции и макросы, составляющие пакет стандартного ввода/вывода, поддерживают продвижение указателя в буфере, ассоциированном с файлом. В случае достижения указателем конца буфера необходимая подкачка символов из файла в буфер (или запись символов из буфера в файл, в случае вывода) производятся функциями стандартного ввода/вывода и самой ОС UNIX. Эти действия системы не видны программе и программисту.
Для разрыва связи между дескриптора файла в Вашей программе и файлом, то есть для его закрытия, используется функция fclose(). После ее успешного выполнения дескриптор может быть закреплен за другим файлом с помощью следующего вызова функции fopen(). Такое переиспользование дескрипторов для различных потоков может быть необходимым, если Ваша программа открывает много файлов. Для выходных файлов рекомендуется вызывать fclose(), поскольку это гарантирует, что перед закрытием файла будет выведено все содержимое ассоциированного с ним буфера. Системный вызов exit() закрывает все открытые в программе файлы, однако этот вызов еще и полностью завершает выполнение программы, поэтому его использование безопасно, только если Вы уверены, что сделано все, что нужно.