perror() 的 C++ 替代方案

Posted

技术标签:

【中文标题】perror() 的 C++ 替代方案【英文标题】:C++ alternative to perror() 【发布时间】:2011-03-20 06:03:08 【问题描述】:

我知道我们可以使用

perror()

在 C 中打印错误。我只是想知道是否有 C++ 替代方案,或者我是否必须在我的程序中包含这个(以及因此 stdio.h)。我试图避免尽可能多的 C 函数。

【问题讨论】:

对于那些不知道,但马上说“使用cerr”的人来说,perror() 的用处在于它实际上解释了errno 并相应地显示它。我认为他想要的解释和控制台输出一样多...... 您能解释一下您想如何打印错误吗? C 函数也包含在 C++ 中,使用它们没有任何问题。 Simon,在 C++ 程序中避免使用类似 C 的打印功能的原因之一是在混合时需要小心(冲洗),例如printfcout,见 ***.com/questions/2708482 【参考方案1】:

你可以这样做:

std::cerr << strerror(errno) << std::endl;

这仍然会调用strerror,所以你实际上只是用一个 C 函数替换了另一个。 OTOH,它确实允许您通过流编写,而不是混合 C 和 C++ 输出,这通常是一件好事。至少 AFAIK,C++ 不会在库中添加任何东西来替代 strerror(除了生成 std::string,我不确定它会从 strerror 发生什么变化)。

【讨论】:

strerror 的 C++ 版本将返回 std::string,大概也是线程安全的,这将是一个很好的改进。 @Tyler:嗯,这当然是可能的,而且会是一个方便的改进。 OTOH,从使用errno 的任何东西中获取线程安全几乎不可避免地使用线程本地存储(即,与使strerror 线程安全所需的内容大致相同)。 @Jerry 我不确定其他线程框架,但 POSIX 线程保证 errno 自动是线程本地的。 strerror 的问题在于它返回一个指向非线程本地静态缓冲区的指针。 @Tyler:我的意思是要让errno 工作,无论如何你都需要拥有并使用TLS,一旦你使用它,你不妨将它用于strerror' s 缓冲区。 @Tyler McHenry:拥有一个创建 std::string 的错误消息创建函数是非常不合适的。如果该函数尝试报告“内存不足”,它将如何工作?我会说采用给定大小的 char* 缓冲区的错误函数是最合适的。它也是“线程安全的”。【参考方案2】:

您可以使用boost::system_error::error_code 类。

#include <boost/system/system_error.hpp>

#include <cerrno>
#include <iostream>

void
PrintError(
        const std::string& message,
        int error
        )

    std::cerr << message << ": " <<
            boost::system::error_code(
                error,
                boost::system::get_system_category()
                ).message()
            << std::endl;


int
main()

    PrintError( "something went wrong!", EINVAL );
    return 0;

如果您还没有使用 boost_system 库,这有点冗长,而且有点矫枉过正。

【讨论】:

如果你碰巧发生了 PrintError("We run out of memory!", EINVAL);当你发现你没有进行内存分配时? 实际上不能使用 boost 库。这必须尽可能“简单”(因为没有更好的术语)。尽量不包括任何第 3 方的东西。不过谢谢!【参考方案3】:

在 C++11 中,我们有 标头,因此您应该可以使用:

std::error_codeerrno, std::generic_category().message();

示例程序:

#include <system_error>
#include <iostream>

int main() 
    std::cout << std::error_codeerrno, std::generic_category().message() << '\n';

这个printsSuccess

另见:

How to convert errno to exception using <system_error> <system_error> categories and standard/system error codes (关于是使用generic_category还是system_category

【讨论】:

以上是关于perror() 的 C++ 替代方案的主要内容,如果未能解决你的问题,请参考以下文章

为啥 perror() 在重定向时会改变流的方向?

在 C 中检查 fwrite 是不是成功,perror

转:perror和strerror的区别

perror strerror使用方法

C和指针 第十五章 错误报告perror和exit

c中perror函数