如何将warn()的输出变为字符串?

时间:2013-02-26 15:56:48

标签: c++ error-handling bsd

如果无法打开文件,我正在使用非标准函数warn()(由BSD提供)输出错误消息,如下所示:

std::string path = get_path() ;
std::ifstream file(path) ;
if (file.is_open()) { /* do something */ }
else {
    warn("%s", path.c_str()) ;
    // uses errno to figure out what the error was and outputs it nicely along with the filename
}

这对于输出它来说非常好,但是如果我想在其他地方使用整个字符串,除了打印它之外怎么办? warn()函数似乎没有将错误写入字符串的表单。我试过自己滚动,但相比之下它似乎非常麻烦(除了没有得到程序的名字):

this->foo((boost::format("%s: %s") % path % strerror(errno)).str()) ;

那么如何将warn()的输出作为字符串?

3 个答案:

答案 0 :(得分:1)

warn将其输出放在标准错误输出上。因此,您必须创建一种机制,将标准错误输出重定向到您可以读回字符串的位置。最直接的方法可能是将标准错误重定向到文件,然后将文件作为字符串读回。例如,您可以尝试使用dup2()来完成此操作(如this question的答案中所述)。

但是,包装您自己的warn版本可能是更好的选择。但是,您可以考虑使用C vsnprintf()函数来实现它。 this question有答案可以解决使用boost::formatvsnprintf()

的问题

答案 1 :(得分:0)

你是对的 - 没有sprintf模拟(即没有假设的swarn函数)。

你的方法似乎可行。

答案 2 :(得分:0)

看起来您的回转会产生类似于:

的结果
path + ": " +  strerror(errno);

猜测一下,它所包含的“程序名称”可能只是argv[0],因此您显然可以生成大约相当于warn的{​​{1}}只返回std::string的东西在这个一般订单上:

std::string warn_s(std::string const &path) { 
    char *pname = strrchr(argv[0], '/');
    if (pname == NULL)
        pname = argv[0];
    return path + pname + ":  " + strerror(errno);
}

这里的主要困难是argvmain的本地,所以你可能需要将它保存到main中的可访问位置,或者使用一些非标准机制来重新 - 检查函数中的数据。

不幸的是,我能找到的warn文档很差,如果你想要精确复制它的输出,可能需要进行一些测试/试错。