Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Обработка ошибок - stderr и exit

Поиск
Обработка ошибок в CAT неидеальна. Неудобство заключает-ся в том, что если один из файлов по некоторой причине ока-зывается недоступным, диагностическое сообщение об этом пе-чатается в конце объединенного вывода. Это приемлемо, есливывод поступает на терминал, но не годится, если вывод пос-тупает в некоторый файл или через поточный (PIPELINE) меха-низм в другую программу. Чтобы лучше обрабатывать такую ситуацию, к программеточно таким же образом, как STDIN и STDOUT, присоединяетсявторой выходной файл, называемый STDERR. Если это вообщевозможно, вывод, записанный в файле STDERR, появляется натерминале пользователя, даже если стандартный вывод направ-ляется в другое место. Давайте переделаем программу CAT таким образом, чтобысообщения об ошибках писались в стандартный файл ошибок. "INCLUDE 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) \(PRINTF(STDERR, "CAT: CAN'T OPEN,%S\N", ARGV); EXIT(1); \) ELSE \(FILECOPY(FP); \) EXIT(0); \) Программа сообщает об ошибках двумя способами. Диагностичес-кое сообщение, выдаваемое функцией FPRINTF, поступает вSTDERR и, таким образом, оказывается на терминале пользова-теля, а не исчезает в потоке (PIPELINE) или в выходном фай-ле. Программа также использует функцию EXIT из стандартнойбиблиотеки, обращение к которой вызывает завершение выполне-ния программы. Аргумент функции EXIT доступен любой програм-ме, обращающейся к данной функции, так что успешное или неу-дачное завершение данной программы может быть проверено дру-гой программой, использующей эту в качестве подзадачи. Посоглашению величина 0 в качетсве возвращаемого значения сви-детельствует о том, что все в порядке, а различные ненулевыезначения являются признаками нормальных ситуаций. Функция EXIT вызывает функцию FCLOSE для каждого откры-того выходного файла, с тем чтобы вывести всю помещенную вбуферы выходную информацию, а затем вызывает функцию _EXIT.Функция _EXIT приводит к немедленному завершению без очисткикаких-либо буферов; конечно, при желании к этой функции мож-но обратиться непосредственно.

Ввод и вывод строк

Стандартная библиотека содержит функцию FGETS, совершен-но аналогичную функции GETLINE, которую мы использовали навсем протяжении книги. В результате обращения FGETS(LINE, MAXLINE, FP) следующая строка ввода (включая символ новой строки) считы-вается из файла FP в символьный массив LINE; самое большоеMAXLINE_1 символ будет прочитан. Результирующая строка за-канчивается символом \ 0. Нормально функция FGETS возвращаетLINE; в конце файла она возвращает NULL. (Наша функцияGETLINE возвращает длину строки, а при выходе на конец файла- нуль). Предназначенная для вывода функция FPUTS записываетстроку (которая не обязана содержать символ новой строки) вфайл: FPUTS(LINE, FP) Чтобы показать, что в функциях типа FGETS и FPUTS нетничего таинственного, мы приводим их ниже, скопированныминепосредственно из стандартной библиотеки ввода-вывода: #INCLUDE 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) 7 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 -------------- Напишите программу печати набора файлов, которая начина-ет каждый новый файл с новой страницы и печатает для каждогофайла заголовок и счетчик текущих страниц.

Несколько разнообразных функций

Стандартная библиотека предоставляет множество разнооб-разных функций, некоторые из которых оказываются особеннополезными. Мы уже упоминали функции для работы со строками:STRLEN, STRCPY, STRCAT и STRCMP. Вот некоторые другие.

7.9.1. Проверка вида символов и преобразования

Некоторые макросы выполняют проверку символов и преобра-зования: SALPHA(C) не 0, если "C" алфавитный символ, 0 - если нет. SUPPER(C) Не 0, если "C" буква верхнего регистра, 0 - если нет. SLOWER(C) Не 0, если "C" буква нижнего регистра, 0 - если нет. SDIGIT(C) Не 0, если "C" цифра, 0 - если нет. SSPACL(C) Не 0, если "C" пробел, табуляция или новая строка, 0 - если нет. OUPPER(C) Преобразует "C" в букву верхнего регистра. OLOWER(C) Преобразует "C" в букву нижнего регистра.

Функция UNGETC

Стандартная библиотека содержит довольно ограниченнуюверсию функции UNGETCH, написанной нами в главе 4; она назы-вается UNGETC. В результате обращения UNGETC(C,FP) символ "C" возвращается в файл FP. Позволяется возвращать вкаждый файл только один символ. Функция UNGETC может бытьиспользована в любой из функций ввода и с макросами типаSCANF, GETC или GETCHAR.

Обращение к системе

Функция SYSTEM(S) выполняет команду, содержащуюся в сим-вольной строке S, и затем возобновляет выполнение текущейпрограммы. Содержимое S сильно зависит от используемой опе-рационной системы. В качестве тривиального примера, укажем,что на системе UNIX строка SYSTEM("DATE"); приводит к выполнению программы DATE, которая печатает датуи время дня.

Управление памятью

Функция CALLOC весьма сходна с функцией ALLOC, использо-ванной нами в предыдущих главах. В результате обращения CALLOC(N, SIZEOF(OBJCCT)) возвращается либо указатель пространства, достаточного дляразмещения N объектов указанного размера, либо NULL, еслизапрос не может быть удволетворен. Отводимая память инициа-лизируется нулевыми значениями. Указатель обладает нужным для рассматриваемых объектоввыравниванием, но ему следует приписывать соответствующийтип, как в CHAR *CALLOC(); INT *IP; IP=(INT*) CALLOC(N,SIZEOF(INT)); Функция CFREE(P) освобождает пространство, на котороеуказывает "P", причем указатель "P" певоначально должен бытьполучен в результате обращения к CALLOC. Здесь нет никакихограничений на порядок освобождения пространства, но будетнеприятнейшей ошибкой освободить что-нибудь, что не было по-лучено обращением к CALLOC. Реализация программы распределения памяти, подобнойCALLOC, в которой размещенные блоки могут освобождаться впроизвольном порядке, продемонстрирована в главе 8.

* 8. Интерфейс системы UNIX *

Материал этой главы относится к интерфейсу между с-прог-раммами и операционной системой UNIX. Так как большинствопользователей языка "C" работают на системе UNIX, эта главаокажется полезной для большинства читателей. даже если выиспользуете с-компилятор на другой машине, изучение приводи-мых здесь примеров должно помочь вам глубже проникнуть в ме-тоды программирования на языке "C". Эта глава делится на три основные части: ввод/вывод,система файлов и распределение памяти. Первые две частипредполагают небольшое знакомство с внешними характеристика-ми системы UNIX. В главе 7 мы имели дело с системным интерфейсом, которыйодинаков для всего многообразия операционных систем. На каж-дой конкретной системе функции стандартной библиотеки должныбыть написаны в терминах ввода-вывода, доступных на данноймашине. В следующих нескольких разделах мы опишем основнуюсистему связанных с вводом и выводом точек входа операцион-ной системы UNIX и проиллюстрируем, как с их помощью могутбыть реализованы различные части стандартной библиотеки.

Дескрипторы файлов

В операционной системе UNIX весь ввод и вывод осуществ-ляется посредством чтения файлов или их записи, потому чтовсе периферийные устройства, включая даже терминал пользова-теля, являются файлами определенной файловой системы. Этоозначает, что один однородный интерфейс управляет всеми свя-зями между программой и периферийными устройствами. В наиболее общем случае перед чтением из файла или за-писью в файл необходимо сообщить системе о вашем намерении;этот процесс называется "открытием" файла. Система выясня-ет,имеете ли вы право поступать таким образом (существует лиэтот файл? имеется ли у вас разрешение на обращение к не-му?), и если все в порядке, возвращает в программу небольшоеположительное целое число, называемое дескриптором файла.всякий раз, когда этот файл используется для ввода или выво-да, для идентификации файла употребляется дескриптор файла,а не его имя. (Здесь существует примерная аналогия с исполь-зованием READ (5,...) и WRITE (6,...) в фортране). Вся ин-формация об открытом файле содержится в системе; программапользователя обращается к файлу только через дескриптор фай-ла. Для удобства выполнения обычных операций ввода и выводас помощью терминала пользователя существуют специальные сог-лашения. Когда интерпретатор команд ("SHELL") прогоняетпрограмму, он открывает три файла, называемые стандартнымвводом, стандартным выводом и стандартным выводом ошибок,которые имеют соответственно числа 0, 1 и 2 в качестве деск-рипторов этих файлов. В нормальном состоянии все они связаныс терминалом, так что если программа читает с дескрипторомфайла 0 и пишет с дескрипторами файлов 1 и 2, то она можетосуществлять ввод и вывод с помощью терминала, не заботясьоб открытии соответствующих файлов. Пользователь программы может перенаправлять ввод и выводна файлы, используя операции командного интерпретатора SHELL"<" и ">": PROG OUTFILE В этом случае интерпретатор команд SHELL изменит присваива-ние по умолчанию дескрипторов файлов 0 и 1 с терминала науказанные файлы. Нормально дескриптор файла 2 остается свя-занным с терминалом, так что сообщения об ошибках могут пос-тупать туда. Подобные замечания справедливы и тогда, когдаввод и вывод связан с каналом. Следует отметить, что во всехслучаях прикрепления файлов изменяются интерпретаторомSHELL, а не программой. Сама программа, пока она используетфайл 0 для ввода и файлы 1 и 2 для вывода, не знает ни отку-да приходит ее ввод, ни куда поступает ее выдача.


Поделиться:


Последнее изменение этой страницы: 2016-08-26; просмотров: 259; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.219.70.7 (0.007 с.)