Вы можете использовать perror()
, если вы не против работать в рамках ограничений его форматирования, или вы можете сделать эквивалент:
fprintf(stderr, "Failed to open %s (%d: %s)\n", filename, errno, strerror(errno));
Вы должны смотреть только на errno
после того, как функция сообщила о сбое.Он также может быть установлен после успешной функции.Например, в Solaris, если вывод не является 'tty', вы часто найдете ENOTTY в errno
после успешной операции печати - потому что он проверял, был ли дескриптор выходного файла tty, а на самом деле это не так.Но функция завершилась успешно.
Если в вашем коде больше вызовов функций, чем в показанной мною строке, лучше всего сохранить errno
на ранней стадии - потому что она вмешивается в другие функции (одна измножество недостатков глобальной переменной).Поэтому я часто пишу:
{
int errnum = errno;
...any other processing...
fprintf(stderr, "%s: failed to open %s for reading (%d: %s)\n",
prog_name, file_name, errnum, strerror(errnum));
}
Ну, я пишу логический эквивалент этого;У меня есть библиотека, которая сообщает об ошибках, поэтому я бы написал:
err_sysrem("failed to open %s for reading", file_name);
Все функции в пакете запускаются err_
.Функция err_sysrem()
является примечанием (не завершается) и включает информацию об ошибке системы - errno
и strerror(errno)
.Если бы я вместо этого позвонил err_syserr()
, это завершило бы программу, а err_remark()
не включало бы информацию из errno
, и ни один не err_error()
.Я нахожу краткость, обеспеченную функциями, полезной.Все функции автоматически включают имя программы в начале сообщения;Вы можете настроить его так, чтобы он включал метки времени, PID или другую информацию.Вы используете err_setarg0(argv[0]);
в main()
, чтобы установить имя программы;Вы можете, конечно, изменить его в любое время.