Вы могли бы рассмотреть возможность использования variadic functions для сообщений об ошибках, они становятся намного более универсальны.
Например
#include <stdarg.h>
void my_error(FILE *out, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(out, fmt, ap);
va_end(ap);
}
Какой может быть вызван как (обратите внимание, я предполагаю, что есть C99 компилятор):
my_error(stderr,
"%s: Invalid range of %ld near line %d", __func__, range, __LINE__);
Это может легко связать с другими ответами предполагая, что коды ошибок могут быть определены в перечислимых списках с постоянным массивом строк для их перевода. Я оставлю это как упражнение для читателя. Очень просто сделать пример выше, принять больше аргументов.
NB: Если вы используете что-то вроде буфера символов [LEN] для пользовательского форматирования печатной строки, измените ее с void на unsigned int, верните количество байтов, которое vsnprintf() не может распечатать, что может быть полезно вызывающему абоненту. Вышеприведенный пример является «безопасным», в котором вам не нужно беспокоиться о перетекании некоторого стекового распределенного буфера с отформатированным сообщением об ошибке неопределенной длины. Или оставьте его как пустоту и распечатайте, что он может (хотя он не может распечатать все), вплоть до вас. Обратный подход к этому подходу не совсем знает длину вариационных аргументов после расширения. В конце концов, вы сообщаете о неожиданных результатах :)
Этот подход позволяет вам больше помочь, передавая содержательные и информативные сообщения об ошибках, а также просто записывая их в любой открытый файл.
Я знаю, что этот пример в основном описывает printf(). Я отправляю его, чтобы показать, насколько легко адаптироваться и расширяться.
Используйте 'fprintf (stderr, ...)', чтобы сообщать об ошибках (или, по крайней мере, нормально писать в 'stderr', а не 'stdout' - или записывать в файл журнала или оба файла журнала и stderr). –