C 打印错误消息

C 打印错误消息,c,C,我只是想知道什么是制作自定义打印错误函数的最佳方法 例如,我在头文件中有一些类似的#定义: #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)

我只是想知道什么是制作自定义打印错误函数的最佳方法

例如,我在头文件中有一些类似的#定义:

#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");
   }
}
//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]);
    }
}
然而,我认为这并不完美,我想做得更好。也许更专业一点,也许更具可扩展性

非常感谢您的建议,

查看一些如何实现日志记录的想法

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


当你需要写一条错误消息时,问问自己这个问题:当我看到这个错误消息时,我需要知道什么?什么可以帮助我解决问题?

您也可以这样做:

if(/*something has gone wrong with socket*/)
{
   print_error(SOCKET_ERR);
}

print_error(int error)
{
   if(error == 0)
   {
       printf("Socket failure\n");
   }
}
//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,
你错了,
听着,呃,
最后一项//这应该是最后一项
}错误代码;
//错误描述..条目数应与枚举中的条目数匹配
常量字符*errorDesc[]=
{
“套接字故障”,
“绑定失败”,
“倾听失败”,
“假人”
};
无效打印错误(错误代码c)
{
//验证。。
如果(c<最后一项)
{
printf(errorDesc[c]);
}
}
< /代码> 您可以考虑使用错误报告,它们变得更加通用。

比如说

#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);
}
这可以很容易地与其他答案相结合,这些答案表明可以在枚举列表中定义错误代码,并使用一个常量字符串数组来翻译它们。我将把它作为练习留给读者。很容易让上面的例子接受更多的论点

注意:如果您使用char buffer[LEN]之类的东西来自定义打印字符串的格式,请将其从void更改为unsigned int,让它返回vsnprintf()无法打印的字节数,这可能对调用方有用。上面的示例是“安全”的,您不必担心在堆栈分配的缓冲区中出现未定义长度的格式化错误消息。或者,让它空着,让它打印它能打印的东西(同时注意它不能打印所有东西),由你决定。这种方法的缺点是不太清楚变量参数一旦扩展后的长度。毕竟,您正在报告意外的结果:)

这种方法通过传递有意义且信息丰富的错误消息,以及简单地将它们记录到任何打开的文件中,让您可以帮助自己


我知道这个例子基本上描述了printf()本身。我发布它是为了展示它是多么容易适应和扩展。

添加问题:错误消息是针对谁的(例如开发人员、用户)?哪些信息有用取决于受众。以下是GUI错误,但通常包含错误消息的有用信息:大多数系统为“非错误”保留0。在C99中,您可以使用指定的初始值设定项,如:
[SOCKET\u ERR]=“SOCKET failure”、
,这大大提高了errorDesc初始值设定项的可靠性。使用“fprintf(stderr,…”)报告错误(或者,至少通常写入“stderr”而不是“stdout”-或者写入日志文件,或者同时写入日志文件和stderr)。您好。我认为这听起来是最好的主意。你知道使用过这个函数的链接吗?C99函数的名称是“
”而不是“
”而不是“
”函数。@Jonathan Leffler:是的,你是对的。我已经太习惯于油嘴滑舌的生活了。