打印错误消息
我只是想知道什么是使自定义打印错误功能的最佳途径。打印错误消息
例如,我有一些#define语句像这样的头文件:
#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");
}
}
不过,我不认为这个完美的,并希望做更好的事情。也许更专业一点,也许更具可扩展性。
非常感谢任何建议,
您可以考虑使用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()本身。我发布它来展示适应和扩展是多么容易。
你好。我认为这听起来像是最好的主意。你知道这些已被使用的任何链接吗? – ant2009 2009-11-05 11:03:08
函数的C99名称是“__func__”,而不是“__FUNCTION__”。 – 2009-11-05 13:28:36
@Jonathan Leffler:是的,你是对的。我太习惯glibc生物的舒适。 – 2009-11-05 14:25:06
退房log4c的一些想法如何实现日志记录。
这里有一些建议:不要只打印“有错误”。尽可能多地提供信息:哪个IP地址?错误代码?你的代码试图达到什么目的?
当你需要编写一个错误信息,问自己这个问题:我还需要知道,当我看到这个错误讯息? 修复什么会帮我解决这个问题?
添加到问题:谁是(例如开发人员,用户)的错误消息?哪些信息有用取决于观众。以下是GUI错误信息,但通常包含错误消息的有用信息:http://developer.apple.com/mac/library/documentation/UserExperience/Conceptual/AppleHIGuidelines/XHIGWindows/XHIGWindows.html#//apple_ref/doc/uid/20000961-TPXREF23 http://msdn.microsoft.com/en-us/library/ms995351.aspx – outis 2009-11-05 08:48:34
你也可以做这样的事情:
//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]);
}
}
大多数系统为'没有错误'保留0。在C99中,可以使用指定的初始化程序,如:[SOCKET_ERR] =“套接字故障”,这极大地提高了errorDesc初始化程序的可靠性。 – 2009-11-05 08:50:58
使用“fprintf中(错误,...)”报告错误(或者,至少,通常写为“标准错误”,而不是“标准输出” - 或写入日志文件,或两者日志文件和标准错误)。 – 2009-11-05 08:51:52