1

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()'s 输出作为字符串呢?

4

3 回答 3

1

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

但是,包装您自己的版本warn可能是更好的选择。不过,您可以考虑使用 Cvsnprintf()函数来实现它。这个问题的答案可以同时解决 usingboost::formatvsnprintf().

于 2013-02-26T16:08:01.527 回答
0

您的旋转似乎会产生类似于以下内容的结果:

path + ": " +  strerror(errno);

猜测一下,它所包含的“程序名称”可能只是argv[0],因此您显然可以生成与您的大致等价的warn仅返回 astd::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);
}

这里的主要困难是它argv是本地的main,因此您可能需要将其保存到 main 中的可访问位置,或者使用一些非标准机制在您的函数中重新检索该数据。

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

于 2013-02-26T16:16:13.727 回答
0

你是对的——没有sprintf类比(即没有假设swarn函数)。

你的方法似乎可行。

于 2013-02-26T16:08:29.737 回答