Читаем Linux программирование в примерах полностью

Многие системы предоставляют также другие значения ошибок, а в более старых системах может не быть всех перечисленных значений ошибок. Полный список следует проверить с помощью справочных страниц intro(2) и errno(2) для локальной системы.

ЗАМЕЧАНИЕ. errno следует проверять лишь после того, как возникла ошибка и до того, как сделаны дальнейшие системные вызовы. Начальное значение той переменной 0. Однако, в промежутках между ошибками ничто не изменяет ее значения, это означает, что успешный системный вызов не восстанавливает значение 0. Конечно, вы можете вручную установить ее в 0 в самом начале или когда захотите, однако это делается редко.

Сначала мы используем errno лишь для сообщений об ошибках. Для этого имеются две полезные функции. Первая — perror():

#include /* ISO С */


void perror(const char *s);

Функция perror() выводит предоставленную программой строку, за которой следует двоеточие, а затем строка, описывающая значение errno:

if (some_system_call(param1, param2) < 0) {

 perror("system call failed");

 return 1;

}

Мы предпочитаем функцию strerror(), которая принимает параметр со значением ошибки и возвращает указатель на строку с описанием ошибки:

#include /* ISO С */


char *strerror(int errnum);

strerror() предоставляет для сообщений об ошибках максимальную гибкость, поскольку fprintf() дает возможность выводить ошибки любым нужным нам способом, наподобие этого.

if (some_system_call(param1, param2) < 0) {

 fprintf(stderr, "%s: %d, %d: some_system_call failed: %s\n",

  argv[0], param1, param2, strerror(errno));

 return 1;

}

По всей книге вы увидите множество примеров использования обеих функций.

4.3.2. Стиль сообщения об ошибках

Для использования в сообщениях об ошибках С предоставляет несколько специальных макросов. Наиболее широкоупотребительными являются __FILE__ и __LINE__, которые разворачиваются в имя исходного файла и номер текущей строки в этом файле. В С они были доступны с самого начала. C99 определяет дополнительный предопределенный идентификатор, __func__, который представляет имя текущей функции в виде символьной строки. Макросы используются следующим образом:

if (some_system_call(param1, param2) < 0) {

 fprintf(stderr, "%s: %s (%s %d): some_system_call(%d, %d) failed: %s\n",

  argv[0], __func__, __FILE__, __LINE__,

  param1, param2, strerror(errno));

 return 1;

}

Здесь сообщение об ошибке включает не только имя программы, но также и имя функции, имя исходного файла и номер строки. Полный список идентификаторов, полезных для диагностики, приведен в табл. 4.2.


Таблица 4.2. Диагностические идентификаторы C99

ИдентификаторВерсия СЗначение
__DATE__C89Дата компиляции в виде «Mmm nn yyyy»
__FILE_ОригинальнаяИмя исходного файла в виде «program.c»
__LINE__ОригинальнаяНомер строки исходного файла в виде 42
__TIME__C89Время компиляции в виде «hh:mm:ss»
__func__C99Имя текущей функции, как если бы было объявлено const char __func__[] = "name"

Использование __FILE__ и __LINE__ было вполне обычно для ранних дней Unix, когда у большинства людей были исходные коды и они могли находить ошибки и устранять их. По мере того, как системы Unix становились все более коммерческими, использование этих идентификаторов постепенно уменьшалось, поскольку знание положения в исходном коде дает немного пользы, когда имеется лишь двоичный исполняемый файл.

Сегодня, хотя системы GNU/Linux поставляются с исходными кодами, указанный исходный код часто не устанавливается по умолчанию. Поэтому использование этих идентификаторов для сообщений об ошибках не представляет дополнительной ценности. GNU Coding Standards даже не упоминает их.

4.4. Ввод и вывод

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

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

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных