【问题标题】:sprintf to std::string directly?sprintf 到 std::string 直接?
【发布时间】:2012-01-05 20:18:15
【问题描述】:

我有兴趣(出于各种原因)使用 sprintf 格式化,结果是 std::string 对象。我想出的最直接的语法方式是:

char* buf;
sprintf(buf, ...);
std::string s(buf);

还有其他想法吗?

【问题讨论】:

标签: c++ performance printf stdstring


【解决方案1】:

不要使用 printf 函数行在 C++ 中进行格式化。使用类型安全且不需要用户提供特殊格式字符的流(在本例中为字符串流)的语言特性。

如果你真的想要这样做,你可以在你的字符串中预先分配足够的空间,然后调整它的大小,尽管我不确定这是否比使用临时 char 缓冲区更有效数组:

std::string foo;
foo.resize(max_length);
int num_bytes = snprintf(&foo[0], max_length, ...);
if(num_bytes < max_length)
{
    foo.resize(num_bytes);
}

【讨论】:

  • 我想我曾经听说过 basic_string 的元素不能保证是连续的,所以像这样使用 &amp;foo[0] 在技术上是未定义的行为。我也认为我听说这在 C++11 中有所改变,但我不确定。
  • @Benjamin:C++03 本身不需要std::basic_string&lt;&gt; 的连续存储,但library issue 530 需要它,而且我所知道的每个编译器供应商多年来都坚持这一点。另外,C++11 需要它是正确的。
  • 应该max_length 计算终止的空字节吗?我想我曾经听说过basic_string 不使用空终止。
  • 流接口不可国际化。顺便提一句。您可以通过将 NULL 指针传递给 snprintf 来获取字符串的长度。
【解决方案2】:

如果你绝对想使用sprintf,没有比你写的更直接的方法了。

sprintf 写入一个 C 字符串 str 指向的数组

如果你想把这个C string 转换成std::string,没有比你写的更好更安全的方法了。

【讨论】:

  • snprintf 在几乎所有系统上都可用时,永远不要提倡sprintf(假设C++ 流不是一个选项)。
【解决方案3】:

回复here。要获取所需的缓冲区长度,请调用:

snprintf( nullptr, 0, format, args... )

您可以编写可以这样使用的短函数:

std::string s = string_sprintf("%g, %g\n", 1.23, 0.001);

链接的 stackoverflow 答案中的示例。

【讨论】:

    猜你喜欢
    • 2010-12-21
    • 1970-01-01
    • 1970-01-01
    • 2016-08-22
    • 2021-02-24
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    • 2017-01-05
    相关资源
    最近更新 更多