Jakob Sachs
Jakob Sachs

Reputation: 715

Is there an easy way to add leading zeros to a string created via std::to_string(int)?

I got the following std::string that I partially create through converting an int to a string:

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

Example output:

FPS: 60

Now, I would like to add leading zeros specifically to the int part, such that I get this output:

FPS: 060

I already know how to achieve this for stdout with std::cout << std::setfill('0') << std::setw(5) .

But I haven't found a solution for the simple std::to_string() conversion.

Upvotes: 3

Views: 1465

Answers (3)

Tzig
Tzig

Reputation: 841

Use a stringstream.

It behaves exactly like std::cout but has a method str() to get the string you created.

For your problem it would probably look like this:

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

Edit: To test the performance of this I created a dumb test program:

#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;
}

and compiled it with g++ -O3 main.cpp. I then opened a terminal and started the program through time:

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

So 1.53s for 100k iterations (15.3µs per iteration on average) on my Intel(R) Core(TM) i5-8500 CPU @ 3.00GHz CPU running a Linux 5.13.5 kernel the latest libstdc++

It's very long from an instruction perspective, tens of thousands of instructions is costly on small micro-processor, but on a modern system it's hardly ever a problem.

Upvotes: 6

Ted Lyngmo
Ted Lyngmo

Reputation: 117298

You could count the length of the converted string and use that to create a string with zeroes:

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;

A performance test comparing using this "strings only" approach to that of using std::stringstream may be interesting if you do this formatting a lot:

quick-bench.com enter image description here

Upvotes: 5

Jarod42
Jarod42

Reputation: 217275

In C++20, you might use std::format

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

Upvotes: 6

Related Questions