Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 佩罗为什么不';在错误处理的代码中不常见吗?_C++_C_Error Handling - Fatal编程技术网

C++ 佩罗为什么不';在错误处理的代码中不常见吗?

C++ 佩罗为什么不';在错误处理的代码中不常见吗?,c++,c,error-handling,C++,C,Error Handling,查看stackoverflow或其他地方的代码,我似乎很少看到perror()被用来报告错误的确切性质。printf更为常见。这是否表明佩罗有问题或缺失?由于它提供了更好的信息,我希望它会被更频繁地使用。perror()不会准确地告诉您错误发生的行号,而printf()会帮助您确定打印它的确切行号。因此,我认为它在调试中更有用,据我所知,perror()没有任何错误。…我个人更喜欢strerror(),它做的事情大致相同,但允许您将错误消息与printf或类似函数一起使用,从而提供更有用的功能[

查看stackoverflow或其他地方的代码,我似乎很少看到perror()被用来报告错误的确切性质。printf更为常见。这是否表明佩罗有问题或缺失?由于它提供了更好的信息,我希望它会被更频繁地使用。

perror()不会准确地告诉您错误发生的行号,而printf()会帮助您确定打印它的确切行号。因此,我认为它在调试中更有用,据我所知,perror()没有任何错误。…

我个人更喜欢
strerror()
,它做的事情大致相同,但允许您将错误消息与printf或类似函数一起使用,从而提供更有用的功能[发送给程序的编码器或用户,具体取决于错误类型]

例如:

errno = 0;
FILE *f = fopen(argv[1], "rb");
if (!f)
{
    fprintf(stderr, "File %s open failed: error code %d ('%s')\n", 
            argv[1], errno, strerror(errno));
    exit(1);
}
这样,我们也知道是哪个文件(假设它是一个复制文件的程序,perror不一定会告诉你它是“源”还是“目标”)

如果该错误是由于编程错误[或“预计不会出错的内容”],您也可以执行以下操作:

#define UNEXPECTED(cond) do { if (cond) { do_unexpected(errno, #cond, __FILE__, __LINE__); } while(0)

void do_unexpected(int err, const char* cond, const char *file, int line)
{
    fprintf(stderr, "Unexpected error %s [errno=%d, errstr=%s] at %s:%d", 
            cond, err, strerror(errno), file, line);
    exit(1);
}

errno = 0;
FILE *config = fopen("config.txt", "r");

UNEXPECTED(!config); 

... 
// setting errno
if(!foo1(bar))
    throw_errno_exception("foo1");

// returning errorcode
if(int e = foo2(bar))
    throw_exception(e, "foo2");

这是假设您不希望删除“config.txt”,例如[这通常是非常糟糕的编程,但可能有一个合理的原因…]如果在进行标准库调用之前将
errno
设置为零,而该调用失败,并且它是使用
errno
来描述失败原因的调用之一,那么
perror
strerror
可能会提供有用的解释。大多数人不注意
errno
,更不用说如何使用它了这是一个较简单的时间的工件。

< P>因为我使用C++,我不使用PrtffE()和Co,并且在启动时调用SycCyWuStdio(false)。而且,这个函数的问题是它只允许在本地打印错误。
#define UNEXPECTED(cond) do { if (cond) { do_unexpected(errno, #cond, __FILE__, __LINE__); } while(0)

void do_unexpected(int err, const char* cond, const char *file, int line)
{
    fprintf(stderr, "Unexpected error %s [errno=%d, errstr=%s] at %s:%d", 
            cond, err, strerror(errno), file, line);
    exit(1);
}

errno = 0;
FILE *config = fopen("config.txt", "r");

UNEXPECTED(!config); 

... 
// setting errno
if(!foo1(bar))
    throw_errno_exception("foo1");

// returning errorcode
if(int e = foo2(bar))
    throw_exception(e, "foo2");
首先,并不是每个函数都使用errno。特别是对于新代码,我也不会这样做,而是返回带有相应错误代码的
int
。因此,对于那些“新”函数,我必须在使用
perror()之前手动设置errno
。但是,我也不希望这样,因为在失败的函数和捕获“n”日志异常的位置之间通常存在很大的差距


现在,在C中,你没有办法把额外的信息传递到堆栈中,就像C++中的异常。因此,在C中记录实际失败的函数和在它失败的地方的任何上下文更重要。

比什么更好的信息?在C++中,你可能使用异常,而使用Pror会简单地打印愚蠢的信息。“错误:成功“。它会打印出fopen、malloc等的确切错误。也许我应该严格保留这个问题。花很多时间编写Windows应用程序?因为在许多更小的嵌入式系统中,不包括支持
perror
的功能。您的代码是否向
perror
提供信息?我非常确定
perror()
与任何其他打印功能一样可能成功—它不应该分配内存。显然,如果没有标准,你就无法通知用户它出了问题。但这听起来像是一个没有标准I/O的嵌入式系统,在这一点上,所有关于处理错误的赌注都没有了。当然,作为一种语言,C是不可能的仍然在嵌入式系统中使用,但您可能根本没有“printf”和“perror”类型的函数。在调用
fopen
之前,不要忘记将
errno
设置为0。虽然这是一件很有用的事情,但我相信如果fopen失败,它不会被“取消设置”,因此在上述情况下实际上并不需要它。执行“if(errno!=0)”的代码当然应该[但无论如何,这是相当糟糕的编码实践,因为errno可以由许多系统函数设置-因此您确实应该使用其他方法来确定是否出错]是的,您是对的;只有当您使用该值来检测错误时,您才必须事先设置它。