在 C 中使用 sprintf 和 std::string

新手上路,请多包涵

我在 C++ 11 中使用 sprintf 函数,方式如下:

 std::string toString()
{
    std::string output;
    uint32_t strSize=512;
    do
    {
        output.reserve(strSize);
        int ret = sprintf(output.c_str(), "Type=%u Version=%u ContentType=%u contentFormatVersion=%u magic=%04x Seg=%u",
            INDEX_RECORD_TYPE_SERIALIZATION_HEADER,
            FORAMT_VERSION,
            contentType,
            contentFormatVersion,
            magic,
            segmentId);

        strSize *= 2;
    } while (ret < 0);

    return output;
}

有没有更好的方法来做到这一点,而不是每次检查预留空间是否足够?为了将来添加更多东西的可能性。

原文由 Dan The Man 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

即使您事先检查了字符串的容量,您的构造 - 写入c_str() 接收的缓冲区也是 未定义的行为。 (返回值是指向 const char 的指针,函数本身标记为 const ,这是有原因的。)

不要混合使用 C 和 C++, 尤其是 不要写入内部对象表示。 (这破坏了非常基本的 OOP。)使用 C++,以确保类型安全,并且不会遇到转换说明符/参数不匹配,如果没有别的。

 std::ostringstream s;
s << "Type=" << INDEX_RECORD_TYPE_SERIALIZATION_HEADER
  << " Version=" << FORMAT_VERSION
  // ...and so on...
  ;
std::string output = s.str();

选择:

 std::string output = "Type=" + std::to_string( INDEX_RECORD_TYPE_SERIALIZATION_HEADER )
                   + " Version=" + std::to_string( FORMAT_VERSION )
                   // ...and so on...
                   ;

原文由 DevSolar 发布,翻译遵循 CC BY-SA 3.0 许可协议

您可以使用 sprintf() 的实现到 std::string 我写的使用 vsnprintf() 在引擎盖下。

它将格式字符串拆分为纯文本部分,这些部分仅复制到目标 std::string 和格式字段部分(例如 %5.2lf ),它们首先是 vsnprintf() 编辑到缓冲区,然后附加到目标。

https://gitlab.com/eltomito/bodacious-sprintf

原文由 eltomito 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题