有没有一种简单的方法可以将前导零添加到通过 std::to_string(int) 创建的字符串中?

Posted

技术标签:

【中文标题】有没有一种简单的方法可以将前导零添加到通过 std::to_string(int) 创建的字符串中?【英文标题】:Is there an easy way to add leading zeros to a string created via std::to_string(int)? 【发布时间】:2021-08-06 11:21:12 【问题描述】:

我通过将int 转换为string 部分创建了以下std::string

std::string text = std::string("FPS: " + std::to_string(1000 / d));

示例输出:

FPS:60

现在,我想将前导零专门添加到 int 部分,以便得到以下输出:

FPS:060

我已经知道如何使用std::cout << std::setfill('0') << std::setw(5) stdout 实现这一目标。

但我还没有找到简单的std::to_string() 转换的解决方案。

【问题讨论】:

sprintf 可以工作。 【参考方案1】:

使用stringstream。

它的行为与 std::cout 完全一样,但有一个方法 str() 来获取您创建的字符串。

对于您的问题,它可能看起来像这样:

std::stringstream ss;
ss << "FPS: " << std::setfill('0') << std::setw(5) << std::to_string(1000 / d);
std::string text(ss.str());

编辑:为了测试它的性能,我创建了一个愚蠢的测试程序:

#include <sstream>
#include <iomanip>

int main()

    std::stringstream ss;

    for(int i=0; i<100000; i++)
    
        ss.clear();
        ss << "FPS: " << std::setfill('0') << std::setw(5) << std::to_string(i);
        std::string text(ss.str());
    

    return 0;

并用g++ -O3 main.cpp 编译它。然后我打开一个终端并通过time启动程序:

$ time ./a.out
./a.out  1,53s user 0,01s system 99% cpu 1,536 total

所以在我的Intel(R) Core(TM) i5-8500 CPU @ 3.00GHz CPU 上运行 100k 次迭代需要 1.53 秒(平均每次迭代 15.3 微秒),运行 Linux 5.13.5 内核和最新的 libstdc++

从指令的角度来看它很长,数万条指令在小型微处理器上成本很高,但在现代系统上几乎不是问题。

【讨论】:

啊好吧。效果很好,虽然我不确定字符串流的性能。正如可能已经表明的那样,它被高频调用。 其实第二行应该是ss &lt;&lt; "FPS: " &lt;&lt; std::setfill('0') &lt;&lt; std::setw(3) &lt;&lt; std::to_string(1000 / d); to_string 函数在这里的作用是什么?为什么不ss &lt;&lt; "FPS: " &lt;&lt; std::setfill('0') &lt;&lt; std::setw(3) &lt;&lt; (1000 / d); @JakobSachs 我编辑了我的答案来解决你的两个 cmets 小吹牛,因为字符串流只用于输出,你应该使用std::ostringstream而不是std::stringstream【参考方案2】:

在 C++20 中,您可以使用 std::format

std::format(":03", 1000 / d);

【讨论】:

在这种情况下,您可以包含FPS: 前缀,格式为:std::string text = std::format("FPS: :03", 1000 / d);【参考方案3】:

您可以计算转换后字符串的长度,并使用它来创建一个带零的字符串:

size_t min_len = 3;
std::string text = std::to_string(1000 / d);
if(text.size() < min_len) text = std::string(min_len - text.size(), '0') + text;
text = "FPS: " + text;

比较使用这种“仅字符串”方法与使用std::stringstream 的性能测试可能如果您经常使用这种格式,会很有趣:

quick-bench.com

【讨论】:

也是一个好方法,但可能不太可读。我会说个人品味的问题。谢谢 @JakobSachs 不客气。是的,这确实是个人品味的问题。我自己经常使用stringstreams,所以我没有反对他们:-)

以上是关于有没有一种简单的方法可以将前导零添加到通过 std::to_string(int) 创建的字符串中?的主要内容,如果未能解决你的问题,请参考以下文章

C编程十进制到二进制 - 将前导零添加到递归方法

如何将前导零添加到国家号码?

如何将前导数字标识符(不一定为零)添加到 r 中的字符串

将前导零添加到 Spark 数据框中的列 [重复]

将前导零添加到 awk 变量

在 Python 中使用 for 循环在日期列中添加前导零