|
Программирование >> Структура ядра и системные вызовы
в дополнение к упомянутым функциям, в <stdlib.h> объявляются также функции, которые применяются при завершении выполняемых программ: void exit ( int status code ); int atexit ( void (*cleanup fnptr)(vold)); void abort ( void ); Функция exit должна быть знакома читателям, так как она используется: для завершения пользовательских программ (процессов) и возврашает цело-; численный код завершения в вызывающий shell. Согласно правилам, принятым в ОС UNIX, нулевое значение аргумента statusjcode означает, что программа выполнена успешно. В противном случае значение status code отлично от нуля. Функция atexit может быть вызвана для выполнения функции, определяемой пользователем. Функция atexit используется без аргументов и не возврашает никакого значения. Она вызывается функцией exit и предназначена для выполнения завершающих действий содержащего вызовы этих функций процесса. С помощью нескольких вызовов atexit в процессе можно зарегистрировать несколько функций, и эти функции вызываются (в порядке, обратном порядку регистрации), когда содержащий их процесс вызывает exit. Функция abort вызывается, когда процесс находится в аварийном состоянии. Эта функция завершает процесс и в ОС UNIX обеспечивает создание файла core, содержащего образ процесса. Такие файлы весьма полезны для отладки прерванных процессов. Наконец, в заголовке <stdlib.h> объявляются функция getenv, которая позволяет процессу получать значения переменных среды shell, а также функция putenv, которая дает возможность установить переменную среды в заданное значение. Однако в ANSI С функция putenv не определена, хотя и присутствует в большинстве UNIX-систем. Прототипы функций getenv и putenv выглядят следующим образом: char* getenv ( const char* env name ); int putenv ( const char* env def ); Значение аргумента env name, используемого при вызове getenv - это символьная строка, содержащая имя переменной среды shell. Функция возвращает значение NULL, если данная переменная среды не определена. Значение аргумента envjdef в функции putenv - символьная строка, содержащая имя переменной среды, знак равенства и значение, которое присваивается переменной. В случае успешного выполнения эта функция возврашает нулевое значение, в случае неудачи - ненулевое. в приведенном далее примере выводипгся значедие переменной среды PATH, а затем значение переменной среды СС устанавливается равным с++: char* env = getenv ( PATH ); cout \ PATH\ value is: env \n; if ( putenv( CC=c++ ) ) cerr putenv of CC failedXn ; 4.3. <string.h> в заголовке <string.h> объявляется набор функций, предназначенных для манипулирования символьными строками. Эти функции хорошо известны программистам, работающим на С и С++, и используются почти во всех С-программах, производящих обработку символьных строк. Вот наиболее распространенные строковые функции: int int int char* char* char* char* char* char* char* char* strlen ( const char* str ); strcmp ( const char* strl, const char* str2 ); strncmp ( const char* str1, const char* str2, const int tS strcat ( char* dest, const char* src ); . . strncat ( char* dest, const char* src, const int n ); strcpy ( char* dest, const char* src ); strncpy ( char* dest, const char* src, const int n ); strchr ( const char* str, const char ch ); strrchr ( const char* str, const char ch ); strstr ( const char* str, const char* key ); strpbrk ( const char* str1, const char* delimit); Как используются данные строковые функции показано ниже: Функция Назначение strlen strcmp strncmp strcat strncat Возвращает количество символов аргумента str, оканчивающегося NULL-символом. NULL-символ в возвращаемом значении не учитывается Сравнивает аргументы strl и str2. Возвращает О, если строки одинаковы; в противном случае возвращается ненулевое значение Сравнивает первые п символов строковых аргументов strl и str2. Возвращает О, если символы совпадают; в противном случае возвращается ненулевое значение Присоединяет строку аргумента src к строке аргумента dest. К результирующей строке rfe.?/добавляется NULL-символ. Возврашает адрес строки аргумента dest Присоединяет первые п символов строки аргумента src к строке аргумента dest К результирующей строке dest добавляется NULL-символ. Возвращает адрес строки аргумента dest функция Назначение Копирует содержимое строки аргумента src, включая завершающий NULL-символ, в dest. Возвращает адрес строки аргумента dest Заменяет первые я символов строки аргумента dest строкой аргумента src. Если размер строки аргумента src равен или больше , то NULL-символ не копируется. Возвращает адрес строки аргумента dest Ищет в строке str первый экземпляр символа ch. Возвращает адрес* символа ch в строке л7гили NULL, если ch не найден Ищет в строке str последний экземпляр символа ch. Возвращает адрес символа ch в строке str или NULL, если ch не найден Ищет в строке sir первый экземпляр символьной строки key. Возвращает адрес строки key в строке str или NULL, если key не найдена Ищет в строке str экземпляр любого символа, указанного в аргументе delimit. Возвращает адрес совпавшего символа в строке str или NULL, если совпадение не обнаружено В дополнение к указанным рассмотрим еще несколько полезных функций, о которых программисты, работающие на С и С++, как правило, не знают. 4.3.1. strspn, strcspn Прототипы функций strspn и strcspn выглядят таким образом: strcpy strncpy strchr strrchr strstr strpbrk const char* strspn ( char* str, const char* delimit ); const char* strcspn ( char* str, const char* delimit ); Функция strspn возвращает в str число начальных символов, которые совпадают с символами, указанными в аргументе delimit. Эта функция полезна для пропуска начальных разделительных символов в строке. В нашем примере возвращается адрес следующего не являющегося пробельным символа во входном аргументе buf. finclude <string.h> char* skip spaces ( char* buf ) return buf + strspn( buf, \t\n ) Функция strcspn возвращает число начальных символов в строке str, которые не указаны в аргументе delimit. Эта функция полезна для поиска следующего разделительного символа в символьной строке. В представленном ниже примере возвращается адрес следующей лексемы во входном аргументе buf отделенной одним из пробельных символов: t #,include .<string.h> ; ; char* get token ( char* buf ) char* ptr = buf + strspn( buf, \n\t ); /* найти начало лексемы */ char* endptr = ptr + strcspn(ptr, \n\t ); /* найти разделитель после лексемы */ 4 if ( endptr > ptr ) *endptr = \0; :>if ( *ptr ) return ptr; /* возщитить лексе */ else return NULL; /* конец строки. Лексемы нет */ 4.3.2. strtok Прототип функции strtok выглядит следующим образом: const char* strtok ( char* str, const char* delimit ); Эта функция разбивает аргумент str на одну или несколько лексем. Лексемы отделяются друг от друга символами, указанными в аргументе delimit. Если аргумент j/r является адресом символьной строки, то функция strtok возвращает указатель на первую лексему*- етроке сли же аргумент str имеет значение NULL, то функция возвращает указатель на следующую лексему в ранее заданной строке. Функция возвращает NULL, если лексем в строке больше нет. Покажем, как строка может разбиваться на лексемы, разделенные пробельными символами. Каждая полученная лексема направляется на стандартный вывод: : finclude <iostream.h> finclude <string.h> int main( int argc, char* argv[] while ( -argc > 0 ) for (char* tok; tok=strtok(argv[argc], cout tok: tok endl; \n\t ); argv[argc]=0;) Отметим, что функция strtok модифицирует входной аргумент str путем замещения в нем разделительных символов после лексем NULL-символом. Пользователи, которые желают повторно использовать символьные строки, подлежащие синтаксическому анализу функцией strtok, должны заранее сделать их дополнителные копии. Ниже показан один из возможных способов реализации функции strtok. Отметим, что функция имеет статический указатель Iptr, обозначающий позицию следующей лексемы в строке. Кроме того, если после лексемы функция находит разделительный символ, то она замещает его NULL-символом. Таким образом, функция модифицирует входную строку символов, извлекая из нее лексемы. finclude <string.h> char* my strtok ( char* str, const char* delimit ) { static char *lptr; if ( str ) ( /* начать разбор новой строки */ str += strspn( str,delimit ) /* пропустить начальные if (!*str ) return NULL; Iptr = str; else if ( !lptr ) return NULL; разделители */ /* выход, если это NULL-строка */ /* продолжить разбор старой строки */ , /* выход, если лексем больше нет */ char* tokn = Iptr + strspn( Iptr, \t\n ); /* пропустить начальный разделитель */ Iptr = tokn + strcspn( tokn, \t\n ); /* найти следующий i разделитель */ ±f { *tukn S& Iptr > tokn ) ; . *lptr++* -I-XO; завершить лексему NULL-символом else Iptr = NULL; /* найти последнюю лексему в строке */ return *tokn ? tokn : NULL; /* возвратить лексему, если таковая имеется */ 4.3.3. strerror Прототип функции strerror выглядит следующим образом: const char* strerror ( int errno ); Эту функцию можно использовать для получения системного диагностического сообщения. Значение аргумента егто может быть любым кодом ошибки, определенным в файле заголовков <sys/errno.h>, или глобальной переменной егто. Глобальная переменная егто устанавливается при каждом вызове системного API. Если API выполнен успешно, ее значение равно нулю, в противном случае оно отлично от нуля. Возвращаемая строка символов служит только для чтения и не должна переназначаться пользователями. Функция perror может быть вызвана для печати диагностического сообщения, если какой-то системный API завершается неудачей. Функция strerror позволяет пользователям определять их собственные версии функции perror. в следующем примере описывается возможная реализация функции perror с использованием strerror. include <iostream.h> ♦include <string.h> void my perror ( const char* msg header ) { if (msg header && strlen(msg header)) /* печатать, если определено пользователем */ cerr msg header : strerror ( errno ) endl; else cerr strerror ( errno ) endl; /* тест-программа для функции my perror */ int main( int argc, char* argv[] ) FILE *fp; while ( -argc > OtNjK. /* для каждого аргумента командной Строки */ if ( ,(fp = fopen(*++argv, r )) ) /* fp=0 при неудачном открытии файла */ my perror( *argv ); /* печатать дианостическое сообщение */ else fclose ( fр ); /.* закрыть файл, если он открыт нормально */ return 0; 4.4. <memory.h> в заголовке <memory.h> объявляется набор функций, предназначенных для манипулирования байтовым потоком. Эти функции похожи на строковые, но в отличие от них имеют более широкое назначение и могут использоваться для манипулирования несимвольными строковыми объектами, в частности, данные функции можно применять для инициализации, сравнения и копирования объектов типа struct. Вот функции, объявленные в заголовке <memory.h>: void* memset ( const void* memp, int ch, size t len ); int memcmp ( const void* mem1, const void* mem2, size t len ); void* memcpy ( void* dest, const void* src, sizet len ); void* memccpy ( void* dest, const void* src, const int ch, size t len ); void* memchr ( const void* memp, const int ch, size t len ); Функция memset заполняет символом ch первые len байтов области памяти, на которую указывает тетр. Она возвращает адрес тетр. Следующий пример иллюстрирует инициализацию переменной типа stmct Stat NULL-символами:
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |