2009-11-05 197 views
3

我只是想知道什么是使自定义打印错误功能的最佳途径。打印错误消息

例如,我有一些#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"); 
    } 
} 

不过,我不认为这个完美的,并希望做更好的事情。也许更专业一点,也许更具可扩展性。

非常感谢任何建议,

+1

使用“fprintf中(错误,...)”报告错误(或者,至少,通常写为“标准错误”,而不是“标准输出” - 或写入日志文件,或两者日志文件和标准错误)。 – 2009-11-05 08:51:52

回答

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()本身。我发布它来展示适应和扩展是多么容易。

+0

你好。我认为这听起来像是最好的主意。你知道这些已被使用的任何链接吗? – ant2009 2009-11-05 11:03:08

+0

函数的C99名称是“__func__”,而不是“__FUNCTION__”。 – 2009-11-05 13:28:36

+0

@Jonathan Leffler:是的,你是对的。我太习惯glibc生物的舒适。 – 2009-11-05 14:25:06

3

退房log4c的一些想法如何实现日志记录。

这里有一些建议:不要只打印“有错误”。尽可能多地提供信息:哪个IP地址?错误代码?你的代码试图达到什么目的?

当你需要编写一个错误信息,问自己这个问题:我还需要知道,当我看到这个错误讯息? 修复什么会帮我解决这个问题?

+2

添加到问题:谁是(例如开发人员,用户)的错误消息?哪些信息有用取决于观众。以下是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

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]); 
    } 
} 
+3

大多数系统为'没有错误'保留0。在C99中,可以使用指定的初始化程序,如:[SOCKET_ERR] =“套接字故障”,这极大地提高了errorDesc初始化程序的可靠性。 – 2009-11-05 08:50:58