有没有一种简单的方法可以将前导零添加到通过 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 << "FPS: " << std::setfill('0') << std::setw(3) << std::to_string(1000 / d);
to_string
函数在这里的作用是什么?为什么不ss << "FPS: " << std::setfill('0') << std::setw(3) << (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 不客气。是的,这确实是个人品味的问题。我自己经常使用stringstream
s,所以我没有反对他们:-)以上是关于有没有一种简单的方法可以将前导零添加到通过 std::to_string(int) 创建的字符串中?的主要内容,如果未能解决你的问题,请参考以下文章