我见过很多这样做的方法,反转字符串(两次!),使用 setlocale(有时有效,有时无效)这是一个模板解决方案,然后我添加了明确的专业化。这适用于 char*、wchar*、string 和 wstring。我不在这里将数字格式转换为字符串格式,我强烈推荐 to_string 和 to_wstring 它们比 _itoa 等“C”函数快得多...
template<typename T, typename U>
T StrFormatNumber(const T Data) {
const size_t Length = Data.length();
assert(Length > 0);
// if( 0 == Length ) I would log this and return
if (Length < 4) { // nothing to do just return
return Data;
}
constexpr size_t buf_size{ 256 };
assert(((Length)+(Length / 3)) + 1 < buf_size);
if (((Length)+(Length / 3)) + 1 >= buf_size) {
throw std::invalid_argument( "Input buffer too large" );
}
std::array<U, buf_size > temp_buf{};
auto p{ 0 };
temp_buf[0] = Data[0];
for (auto y{ 1 }; y < Length; y++) {
if ((Length - y) % 3 == 0) {
temp_buf[y + p] = ',';
p++;
}
temp_buf[(y + p)] = Data[y];
}
return temp_buf.data();
}
template<typename T = const char*>
std::string StrFormatNum(const char* Data) {
return StrFormatNumber<std::string, char>(std::string(Data));
}
template<typename T= std::string>
std::string StrFormatNum(const std::string Data) {
return StrFormatNumber<std::string, char>(Data);
}
template<typename T = std::wstring>
std::wstring StrFormatNum( const std::wstring Data) {
return StrFormatNumber<std::wstring, wchar_t>(Data);
}
template<typename T = const wchar_t*>
std::wstring StrFormatNum( const wchar_t* Data) {
return StrFormatNumber<std::wstring, wchar_t>(std::wstring(Data));
}
void TestStrFormatNumber() {
constexpr auto Iterations{ 180 };
for (auto l{ 0 }; l < Iterations; l++)
{
{ // std::string
std::string mystr{ "10" };
for (int y{ 0 }; y < Iterations; y++) {
mystr += "1";
auto p = mystr.length();
std::cout << "\r\n mystr = "
<< std::setw(80) << mystr.c_str()
<< "\r\n Length = "
<< std::setw(10) << p
<< "\r\n modulo % 3 = "
<< std::setw(10)
<< p % 3 << " divided by 3 = "
<< std::setw(10) << p / 3
<< "\r\n Formatted = " <<
StrFormatNum((mystr)).c_str() << "\n";
}
}
{ // std::wstring
std::wstring mystr{ L"10" };
for (int y{ 0 }; y < Iterations; y++)
{
mystr += L"2";
auto p = mystr.length();
std::wcout << "\r\n mystr = "
<< std::setw(80) << mystr.c_str()
<< "\r\n Length = "
<< std::setw(10) << p
<< "\r\n modulo % 3 = "
<< std::setw(10) << p % 3
<< " divided by 3 = "
<< std::setw(10) << p / 3
<< "\r\n Formatted = "
<< StrFormatNum((mystr)).c_str()
<< "\n";
}
}
{ // char*
std::string mystr{ "10" };
for (int y{ 0 }; y < Iterations; y++) {
mystr += "3";
auto p = mystr.length();
std::cout << "\r\n mystr = " << std::setw(80) << mystr.c_str()
<< "\r\n Length = " << std::setw(10) << p
<< "\r\n modulo % 3 = " << std::setw(10) << p % 3 << " divided by 3 = " << std::setw(10) << p / 3
<< "\r\n Formatted = " << StrFormatNum((mystr.c_str())).c_str() << "\n";
}
}
{ // wchar*
std::wstring mystr{ L"10" };
for (int y{ 0 }; y < Iterations; y++) {
mystr += L"4";
auto p = mystr.length();
std::wcout << "\r\n mystr = " << std::setw(80) << mystr.c_str()
<< "\r\n Length = " << std::setw(10) << p
<< "\r\n modulo % 3 = " << std::setw(10) << p % 3 << " divided by 3 = " << std::setw(10) << p / 3
<< "\r\n Formatted = " << StrFormatNum((mystr.c_str())).c_str() << "\n";
}
}
}
}
我已经测试了多达 1,000 个空格(当然有更大的缓冲区)