0

在 c++ 中执行此操作的最佳方法是什么(简而言之,使用标准库且易于理解):

std::string s = magic_command("%4.2f", 123.456f)
  • 没有长度限制(char s[1000] = ...)
  • 其中 "%4.2f" 是任何 c 格式字符串(例如,将提供给 printf)

我知道为纯 c 建议的 snprintf malloc 组合

将未知长度的格式化数据写入字符串(C 编程)

但是有没有更好、更简洁的方法来用 C++ 做到这一点?

我也知道建议的 std::ostringstream 方法

在 C++ 中将浮点数转换为 std::string

但我想传递 ac 格式字符串,例如“%4.2f”,但我找不到使用 ostringstream 的方法。

4

5 回答 5

8

您可以尝试Boost.Format

std::string s = boost::str(boost::format("%4.2f") % 123.456f);

它不包含在标准中,但 Boost 与非标准库一样标准。

于 2012-08-20T14:35:57.067 回答
5

我会使用std::stringstream( 与setprecision) 代替,然后使用.str()来获得std::string.

于 2012-08-20T14:35:01.807 回答
5

C++完全抛弃了格式字符串的概念,所以不会有标准的做法。magic_command不过,您可以使用asprintfvasprintf实际上是它的变体)实现自己。

请注意,这*asprintf是 GNU/BSD 扩展。因此,它们在 Windows 上不存在。此外,此解决方案不是类型安全的,并且只接受 POD 类型(因此没有类、结构或联合)。

std::string magic_command(const std::string& format, ...)
{
    char* ptr;
    va_list args;
    va_start(args, format);
    vasprintf(&ptr, format.c_str(), args);
    va_end(args);

    std::unique_ptr<char, decltype(free)&> free_chars(ptr, free);
    return std::string(ptr);
}
于 2012-08-20T14:38:57.680 回答
1

如果你真的想使用你的语法并放弃类型安全,我会写一个小包装类来包装snprintf. 我会从一个小尺寸的本地自动缓冲区(比如 2048?)开始,然后调用snprintf一次。如果成功,则返回std::string从该缓冲区创建的。如果超限,分配std::string正确大小的 a 并重复snprintf.

于 2012-08-20T14:49:50.867 回答
1

给出的所有答案都很好,因为似乎没有真正标准的方式来做我想做的事,我会投票给你们,并接受我自己总结的行动方案:

  • 如果字符串足够短,可以手动估计其大小,请执行此操作,将估计值乘以 4,然后静态分配它。
  • 如果您可以摆脱 stringstream + setprecision,那么就这样做,因为它是标准的
  • 如果没有,并且您愿意编写并包含一个基于 snprintf/检查溢出/动态分配的简短帮助函数,请执行此操作并将其放入您的项目“utils”文件中
  • 最后考虑哪个依赖项对您的项目限制较少(也许您已经在使用其中之一):
    • 如果 boost 限制较少,请使用 Boost.Format
    • 如果 GNU/BSD 扩展限制较少,请使用 asprintf
于 2012-08-21T13:11:09.230 回答