如果无法打开文件,我正在使用非标准函数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()
的输出作为字符串?
答案 0 :(得分:1)
warn
将其输出放在标准错误输出上。因此,您必须创建一种机制,将标准错误输出重定向到您可以读回字符串的位置。最直接的方法可能是将标准错误重定向到文件,然后将文件作为字符串读回。例如,您可以尝试使用dup2()
来完成此操作(如this question的答案中所述)。
但是,包装您自己的warn
版本可能是更好的选择。但是,您可以考虑使用C vsnprintf()
函数来实现它。 this question有答案可以解决使用boost::format
和vsnprintf()
。
答案 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);
}
这里的主要困难是argv
是main
的本地,所以你可能需要将它保存到main中的可访问位置,或者使用一些非标准机制来重新 - 检查函数中的数据。
不幸的是,我能找到的warn
文档很差,如果你想要精确复制它的输出,可能需要进行一些测试/试错。