Ошибка в разделе "2.6. Операции отношения и логические операции"? |
Ввод и вывод
7.7. Обработка ошибок - STDERR и EXIT
Обработка ошибок в cat неидеальна. Неудобство заключается в том, что если один из файлов по некоторой причине оказывается недоступным, диагностическое сообщение об этом печатается в конце объединенного вывода. Это приемлемо, если вывод поступает на терминал, но не годится, если вывод поступает в некоторый файл или через поточный ( pipeline ) механизм в другую программу.
Чтобы лучше обрабатывать такую ситуацию, к программе точно таким же образом, как stdin и stdout, присоединяется второй выходной файл, называемый stderr. Если это вообще возможно, вывод, записанный в файле stderr, появляется на терминале пользователя, даже если стандартный вывод направляется в другое место.
Давайте переделаем программу cat таким образом, чтобы сообщения об ошибках писались в стандартный файл ошибок.
"include <stdio.h> main(argc,argv) /*cat: concatenate files*/ int argc; char *argv[]; { file *fp, *fopen(); if(argc==1) /*no args; copy standard input*/ filecopy(stdin); else while (--argc > 0) if((fp=fopen(*++argv,"r#))==null) { fprintf(stderr, "cat: can't open,%s\n", argv); exit(1); } else { filecopy(fp); } exit(0); }
Программа сообщает об ошибках двумя способами. диагностическое сообщение, выдаваемое функцией printf, поступает в stderr и, таким образом, оказывается на терминале пользователя, а не исчезает в потоке ( pipeline ) или в выходном файле.
Программа также использует функцию exit из стандартной библиотеки, обращение к которой вызывает завершение выполнения программы. Аргумент функции exit доступен любой программе, обращающейся к данной функции, так что успешное или неудачное завершение данной программы может быть проверено другой программой, использующей эту в качестве подзадачи. По соглашению величина 0 в качестве возвращаемого значения свидетельствует о том, что все в порядке, а различные ненулевые значения являются признаками ненормальных ситуаций.
функция exit вызывает функцию fclose для каждого открытого выходного файла, с тем чтобы вывести всю помещенную в буферы выходную информацию, а затем вызывает функцию _exit. функция _exit приводит к немедленному завершению без очистки каких-либо буферов; конечно, при желании к этой функции можно обратиться непосредственно.
7.8. Ввод и вывод строк
Стандартная библиотека содержит функцию fgets, совершенно аналогичную функции getline, которую мы использовали на всем протяжении книги. В результате обращения
fgets(line, maxline, fp)
следующая строка ввода (включая символ новой строки ) считывается из файла fp в символьный массив line ; самое большое maxline-1 символ будет прочитан. Результирующая строка заканчивается символом \0. Нормально функция fgets возвращает line ; в конце файла она возвращает null. (Наша функция getline возвращает длину строки, а при выходе на конец файла - нуль).
Предназначенная для вывода функция fputs записывает строку (которая не обязана содержать символ новой строки ) в файл:
fputs(line, fp)
Чтобы показать, что в функциях типа fgets и fputs нет ничего таинственного, мы приводим их ниже, скопированными непосредственно из стандартной библиотеки ввода-вывода:
#include <stdio.h> char *fgets(s,n,iop) /*get at most n chars from iop*/ char *s; int n; register file *iop; { register int c; register char *cs; cs = s; while(--n>0&&(c=getc(iop)) !=EOF) if ((*cs++ = c)=='\n') break; *cs = '\0'; return((c==EOF && cs==s) ? null : s); } fputs(s,iop) /*put string s on fils iop*/ register char *s; register file *iop; { register int c; while (c = *s++) putc(c,iop); }
Упражнение 7-3
Напишите программу сравнения двух файлов, которая будет печатать первую строку и позицию символа, где они различаются.
Упражнение 7-4
Переделайте программу поиска заданной комбинации символов из "лекции №5" таким образом, чтобы в качестве ввода использовался набор именованных файлов или, если никакие файлы не указаны как аргументы, стандартный ввод. Следует ли печатать имя файла при нахождении подходящей строки?
Упражнение 7-5
Напишите программу печати набора файлов, которая начинает каждый новый файл с новой страницы и печатает для каждого файла заголовок и счетчик текущих страниц.