【问题标题】:How do I get warn()'s output into a string?如何将 warn() 的输出转换为字符串?
【发布时间】:2013-02-27 00:41:49
【问题描述】:

我正在使用非标准函数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() 的输出作为字符串获取?

【问题讨论】:

  • 'warn 从何而来?它当然不是一个标准的 c++ 函数,所以你使用它的 API 的文档可能会帮助更多......
  • @PlasmaHH 它是,嗯,一个标准的 C 函数?
  • @BlacklightShining:它,嗯,不是。
  • @BlacklightShining:是的,嗯,不是。
  • @PlasmaHH 它的手册页说它在标准 C 库中……

标签: c++ error-handling bsd


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    您的方法似乎可行。

    【讨论】:

      【解决方案3】:

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

      path + ": " +  strerror(errno);
      

      猜测,它包含的“程序名称”可能只是argv[0],因此您显然可以生成大致相当于您的warn,它只返回一个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 的文档很差,如果您想精确地复制它的输出,可能需要进行一些测试/反复试验。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-27
        • 1970-01-01
        • 2014-01-20
        • 1970-01-01
        • 1970-01-01
        • 2023-02-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多