我只是想知道制作自定义打印错误函数的最佳方法是什么。
例如,我在头文件中有一些#defines:
#define SOCKET_ERR 0
#define BIND_ERR 1
#define LISTEN_ERR 2
etc
然后可能像这样使用:
if(/*something has gone wrong with socket*/)
{
print_error(SOCKET_ERR);
}
print_error(int error)
{
if(error == 0)
{
printf("Socket failure\n");
}
}
然而,我认为这并不完美,并希望做得更好。也许有点专业,可能更具可扩展性。
非常感谢任何建议,
答案 0 :(得分:3)
查看log4c了解如何实施日志记录的一些想法。
以下是一些建议:不要只打印“有错误”。提供尽可能多的信息:哪个IP地址?错误代码?你的代码试图实现什么?
当您需要编写错误消息时,请问自己这个问题:当我看到此错误消息时,我需要知道什么?什么能帮助我修复这个问题?
答案 1 :(得分:3)
您可以考虑使用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__);
这很容易与其他答案相关联,这表明可以在枚举列表中定义错误代码,并使用常量字符串数组来翻译它们。我将把它作为读者的练习。很容易使上面的例子接受更多的论点。
注意:如果使用char buffer [LEN]之类的东西自定义格式化打印的字符串,将其从void更改为unsigned int,让它返回vsnprintf()无法打印的字节数,这可能对呼叫者,召集者。上面的示例是“安全的”,其中您不必担心使用未定义长度的格式化错误消息过度流动某些堆栈分配的缓冲区。或者,将其保留为无效并将其打印出来(虽然注意它无法打印所有内容),由您决定。回归到这种方法并不完全知道一旦扩展后的可变参数的长度。毕竟,你报告了意想不到的结果:)
这种方法可以让您通过传达有意义且信息丰富的错误消息来帮助自己,并简单地将它们记录到任何打开的文件中。
我知道这个例子基本上描述了printf()本身。我发布它是为了表明适应和扩展是多么容易。
答案 2 :(得分:2)
您也可以这样做:
//Enum for the error codes
typedef enum
{
SOCKET_ERR = 0,
BIND_ERR,
LISTEN_ERR,
LAST_ENTRY //This SHOULD be the last entry
} ErrorCode;
//Error descriptions..number of entries should match the number of entries in Enum
const char* errorDesc[] =
{
"Socket failure",
"Bind failure",
"Listen failure",
"Dummy"
};
void printError(ErrorCode c)
{
//Validate..
if( c < LAST_ENTRY)
{
printf(errorDesc[c]);
}
}