Inspired by @carljalal's answer, I found a similar-but-different answer using reverse iterators. Probably less efficient, but a bit more compact:
#include <string>
#include <iterator>
#include <cctype> // for isdigit
...
void addCommas(std::string& num)
{
// begin at the 3rd digit from the back, advance 3 each time
for (auto it = str.rbegin()+3; it < str.rend(); it += 3)
{
// this handles a negative sign (ignores it)
if (isdigit(*it))
{
// there are currently no string functions dealing with reverse_iterators,
// so use .base() to get it's corresponding forward_iterator
// inserting into a string invalidates any iterators, so "reset" `it`, and
// we have to make the return value into a reverse_iterator
it = std::make_reverse_iterator(str.insert(it.base(), ','));
}
}
}
Note, there is some wariness using .base()
, but all seems to be well for the inputs I tried. Above handles any length number string, with or without a preceding negative sign, but does not handle decimals. Also note that std::make_reverse_iterator
requires c++14 or later.
Some sample inputs and outputs:
1 ==> 1
12 ==> 12
123 ==> 123
-12 ==> -12
-123 ==> -123
1234 ==> 1,234
-1234 ==> -1,234
12134 ==> 12,134
-12134 ==> -12,134
328947328949893 ==> 328,947,328,949,893
-328947328949893 ==> -328,947,328,949,893
9328947328949893 ==> 9,328,947,328,949,893
-9328947328949893 ==> -9,328,947,328,949,893
Demonstration