Есть еще один важный момент относительно функции fopen(), которую мы использовали. Если fopen() не способна открыть требуемый файл, она возвращает значение 'NULL' (определенное в stdio.h как 0). Почему она не смогла открыть файл? Вы можете попросить ее считать файл, который не существует. Вот почему мы имеем в программе строку
Заполнение диска, использование запрещенного имени или некоторые другие причины могут препятствовать открытию файла. Поэтому побеспокойтесь, чтобы их не было - маленькая ошибка может увести вас очень далеко.
Закрыть файл проще.
Закрытие файла: fclose( )
Наш пример показывает, как закрывать файл:
Просто используйте функцию fclose( ). Заметим, что аргументом ее является in, указатель на файл, а не test, имя файла.
Для программы, более серьезной, чем эта, следовало бы посмотреть, успешно ли закрыт файл. Функция fclose( ) возвращает значение 0, если файл закрыт успешно, и -1 в противном случае.
Текстовые файлы с буферизацией
Функции fopen() и fclose() работают с текстовыми файлами с "буферизацией". Под буферизацией мы понимаем, что вводимые и выводимые данные запоминаются во временной области памяти, называемой буфером. Если буфер заполнился, содержимое его передается в блок, и процесс буферизации начинается снова. Одна из основных задач fclose( ) заключается в том, чтобы "освободить" любые частично заполненные буфера, если файл закрыт.
Текстовым считается файл, в котором информация запоминается в виде символов в коде ASCII (или аналогичном). Он отличается от двоичного файла, который обычно используется для запоминания кодов машинного языка. Функции ввода-вывода, о которых мы собираемся рассказать, предназначены только для работы с текстовыми файлами.
Ввод-вывод файла: getc( ) и putc( )
Две функции getc( ) и putc( ) работают аналогично функциям getchar( ) и putchar( ). Разница заключается в том, что вы должны сообщить новичкам, какой файл следует использовать. Таким образом, наш "старый дружище"
предназначен для получения символа от стандартного ввода, а
- для получения символа от файла, на который указывает in. Аналогично функция
предназначена для записи символа ch в файл, на который ссылается указатель out типа FILE. В списке аргументов функции putc( ) этот символ стоит первым, а затем указатель файла. В нашем примере мы использовали
где stdout является указателем на стандартный вывод. Таким образом, этот оператор эквивалентен
Действительно, оператор putchar(ch) определен директивой #define так же как функция putc(ch, stdout) определена в файле stdio.h. Этот ужасный файл к тому же определяет в директиве #define указатели stdout и stdin на стандартный вывод и стандартный ввод системы.
Это выглядит довольно просто? Хорошо, добавим пару полезных новшеств.
ПРОСТАЯ ПРОГРАММА СЖАТИЯ ФАЙЛА
В нашем примере имя файла, который следовало открыть, было записано в программе. Мы нс обязаны считаться с этим ограничением. Используя аргументы командной строки, можно сообщить нашей программе имя файла, который хотим считать. B нашем следующем примере (рис. 15.1) так и происходит. С помощью примитивного приема сжимается содержимое - остается только каждый третий символ. Наконец, сжатая версия размещается в новый файл, имя которого состоит из старого имени с добавкой .red (сокращение слова reduced). Обычно весьма важны первый и последний элементы (аргумент командной строки и добавка к имени файла). Само же сжатие имеет более ограниченное применение, но, как вы увидите, им можно пользоваться.