Читаем UNIX полностью

Оно означает, что fp — указатель на FILE, fopen возвращает указатель на FILE; в имеется описание типа для fopen. Реальный вызов функции fopen:

char *name, *mode;

fr = fopen(name, mode);

Первый аргумент fopen представляет собой имя файла (строку символов). Второй аргумент также является символьной строкой, показывающей, как вы намереваетесь использовать файл; допустимые режимы: читать ("r"), писать ("w") или дописать ("а").

Если файл, который вы открыли для записи или дописывания, не существует, он создается, если это возможно. Открытие для записи существующего файла вызывает уничтожение старого содержимого. Попытка читать несуществующий файл считается ошибкой, так же как и попытка читать или писать файл без разрешения. При возникновении ошибки fopen возвращает значение несуществующего указателя NULL (которое обычно определяется в как (char*)0).

Далее, нужен способ читать или писать файл после того, как он открыт. Есть несколько способов, из которых использование getc и putc самый простой. Функция getc выбирает из файла очередной символ:

с = getc(fp)

помещает в с следующий символ из файла, на который указывает fp. Эта функция возвращает EOF по достижении конца файла. Функция putc аналогична getc:

putc(c, fp)

помещает символ с в файл fp и возвращает с. Функции getc и putc возвращают EOF в случае ошибки.

Когда программа начинает выполняться, уже открыты три файла и имеются их указатели. Это стандартные потоки: входной, выходной и поток диагностики; соответствующие указатели называются stdin, stdout и stderr. Указатели на файлы описаны в > и могут использоваться там, где может быть объект типа FILE*. Они являются не переменными, а константами, так что им нельзя присвоить значения. Вызов getchar() есть getc(stdin), a putchar(c) есть putc(c, stdout). На самом деле все эти четыре "функции" определены в как макрокоманды. Они выполняются быстрее обычных вызовов функций ввиду отсутствия накладных расходов по вызову функции для каждого символа (см. табл. 6.3 с некоторыми другими определениями из ).

stdinСтандартный входной поток
stdoutСтандартный выходной поток
stderrСтандартный поток диагностики
EOFКонец файла; обычно -1
NULLНесуществующий указатель; обычно 0
FILEИспользуется для описания указателей на файлы
BUFSIZОбычно размер буфера ввода вывода (часто 512 или 1024)
getc(fp)Возвращает один символ из потока fp
getchar()getc(stdin)
putc(c,fp)Помещает символ с в поток fp
putchar(c)putс(с,stdout)
feof(fp)Не нуль, если достигнут конец файла для потока fp
ferror(fp)Не нуль, если в потоке fp есть ошибка
fileno(fp)Дескриптор файла для потока fp (см. гл. 7)

Таблица 6.3: Некоторые определения из

Теперь вернемся снова к нашей теме и напишем третью версию vis. Если есть аргументы командной строки, они обрабатываются в порядке очередности, если же аргументов нет, используется стандартный входной поток.

/* vis: make funny characters visible (version 3) */

#include

#include

int strip = 0; /* 1 => discard special characters */

main(argc, argv)

 int argc;

 char *argv[];

{

 int i;

 FILE *fp;

 while (argc > 1 && argv[1][0] == '-') {

  switch (argv[1][1]) {

  case 's': /* -s: strip funny chars */

   strip = 1;

   break;

  default:

   fprintf(stderr, "%s: unknown arg %s\n",

    argv[0], argv[1]);

   exit(1);

  }

  argc--;

  argv++;

 }

 if (argc == 1)

  vis(stdin);

 else

 for (i = 1; i < argc; i++)

  if ((fp=fopen(argv[i], "r")) == NULL) {

   fprintf(stderr, "%s: can't open %s\n",

    argv[0], argv[i]);

Перейти на страницу:

Похожие книги