Язык Си - руководство для начинающих
Шрифт:
Для программы, более серьезной, чем эта, следовало бы посмотреть, успешно ли закрыт файл. Функция fclose возвращает значение 0, если файл закрыт успешно, и – 1 в противном случае.
Текстовые файлы с буферизацией
Функции fopen и fclose работают с текстовыми файлами с "буферизацией". Под буферизацией мы понимаем, что вводимые и выводимые данные запоминаются во временной области памяти, называемой буфером. Если буфер заполнился, содержимое его передается в блок, и процесс буферизации начинается
Текстовым считается файл, в котором информация запоминается в виде символов в коде ASCII (или аналогичном). Он отличается от двоичного файла, который обычно используется для запоминания кодов машинного языка. Функции ввода-вывода, о которых мы собираемся рассказать, предназначены только для работы с текстовыми файлами.
Ввод-вывод файла: getc и putc
Две функции getc и putc работают аналогично функциям getchar и putchar. Разница заключается в том, что вы должны сообщить новичкам, какой файл следует использовать. Таким образом, наш "старый дружище"
ch = getchar;
предназначен для получения символа от стандартного ввода, а
ch = getc(in);
– для получения символа от файла, на который указывает in. Аналогично функция
putc(ch, out);
предназначена для записи символа ch в файл, на который ссылается указатель out типа FILE. В списке аргументов функции putc этот символ стоит первым, а затем указатель файла. В нашем примере мы использовали
putc(ch, stdout);
где stdout является указателем на стандартный вывод. Таким образом, этот оператор эквивалентен
putchar(ch);
Действительно, оператор putchar(ch) определен директивой #define так же как функция putc(ch, stdout) определена в файле stdio.h. Этот ужасный файл к тому же определяет в директиве #define указатели stdout и stdin на стандартный вывод и стандартный ввод системы.
Это выглядит довольно просто? Хорошо, добавим пару полезных новшеств.
ПРОСТАЯ ПРОГРАММА СЖАТИЯ ФАЙЛА
В нашем примере имя файла, который следовало открыть, было записано в программе. Мы нс обязаны считаться с этим ограничением. Используя аргументы командной строки, можно сообщить нашей программе имя файла, который хотим считать. B нашем следующем примере (рис. 15.1) так и происходит. С помощью примитивного приема сжимается содержимое - остается только каждый третий символ. Наконец, сжатая версия размещается в новый файл, имя которого состоит из старого имени с добавкой .red (сокращение слова reduced). Обычно весьма важны первый и последний элементы (аргумент командной строки и добавка к имени файла). Само же сжатие имеет более ограниченное применение, но, как вы увидите, им можно пользоваться.
/* сожмите ваши файлы в 2-3 раза! */
#include <stdio.h>
main(argc, argv)
int argc;
char *argv[ ];
{
FILE *in, *out; /*
int ch;
static char name[20]; /* память для имени выходного файла */
int count = 0;
if(argc < 2) /* проверяет, есть ли входной файл */
printf(" Извините, мне нужно имя файла в качестве аргумента.\n" );
else
{ if((in = fopen(argv[1], "r")) != NULL)
{
strcpy(name, argv[1]; /* копирует имя файла в массив */
strcat(name, ".red"); /* добавляет .red к имени */
out = fopen(name, "w"); /* открывает файл для записи */
while((ch = getc(in)) ! = EOF)
if( count ++ %3 ==0)
putc(ch, out); /* печатает каждый третий символ */
fclose(in);
fclosе(out); }
else
printf(" Я не смогла открыть файл\" %s\" .\n", argv[1]);
} }
РИС. 15.1. Программа сжатия файла.
Мы поместили программу в файл, названный reduce и применили эту программу к файлу, названному eddy, который содержал одну единственную строку
Даже Эдди нас опередил с детским хором.
Была выполнена команда
reduce eddy
и на выходе получен файл, названный eddy.red, который содержит
Дед спел тихо
Какая удача! Наш случайно выбранный файл сделал осмысленное сокращение.
Вот некоторые замечания по программе.
Вспомните, что argc содержит определенное количество аргументов, в число которых входит имя программного файла. Вспомните также, что с согласия операционной системы argv[0] представляет имя программы, т. е. в нашем случае reduce. Вспомните еще, что argv[l] представляет первый аргумент, в нашем случае eddy. Так как сам argv[l] является указателем на строку, он не должен заключаться в двойные кавычки в операторе вызова функции.
Мы используем argc, чтобы посмотреть, есть ли аргумент. Любые избыточные аргументы игнорируются. Помещая в программу еще один цикл, вы могли бы использовать дополнительные аргументы - имена файлов и пропускать в цикле каждый из этих файлов по очереди.
С целью создания нового имени выходного файла мы используем функцию strcpy для копирования имени eddy в массив nаmе. Затем применяем функцию strcat для объединения этого имени с .red.