在 C++ 中使用逗号格式化数字
我想编写一个方法,该方法将接受一个整数并返回该整数的 std::string
以逗号格式化。
声明示例:
std::string FormatWithCommas(long value);
用法示例:
std::string result1 = FormatWithCommas(7800);
std::string result2 = FormatWithCommas(5100100);
std::string result3 = FormatWithCommas(201234567890);
// result1 = "7,800"
// result2 = "5,100,100"
// result3 = "201,234,567,890"
将数字格式化为带逗号的 string
的 C++ 方式是什么?
(额外的好处是还可以处理 double 。)
I want to write a method that will take an integer and return a std::string
of that integer formatted with commas.
Example declaration:
std::string FormatWithCommas(long value);
Example usage:
std::string result1 = FormatWithCommas(7800);
std::string result2 = FormatWithCommas(5100100);
std::string result3 = FormatWithCommas(201234567890);
// result1 = "7,800"
// result2 = "5,100,100"
// result3 = "201,234,567,890"
What is the C++ way of formatting a number as a string
with commas?
(Bonus would be to handle double
s as well.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
使用
std::locale
和std::stringstream
免责声明: 可移植性可能是一个问题并且您可能应该查看传递
""
时使用的区域设置Use
std::locale
withstd::stringstream
Disclaimer: Portability might be an issue and you should probably look at which locale is used when
""
is passed您可以按照 Jacob 的建议进行操作,并使用
""
语言环境进行imbue
- 但这将使用系统默认值,这并不能保证您获得逗号。如果您想强制使用逗号(无论系统默认区域设置如何),您可以通过提供自己的numpunct
方面。例如:You can do as Jacob suggested, and
imbue
with the""
locale - but this will use the system default, which does not guarantee that you get the comma. If you want to force the comma (regardless of the systems default locale settings) you can do so by providing your ownnumpunct
facet. For example:我认为以下答案比其他答案更容易:
这将快速且正确地将逗号插入到您的数字字符串中。
I consider the following answer to be easier than the others:
This will quickly and correctly insert commas into your string of digits.
这是相当老派的方法,我在大循环中使用它以避免实例化另一个字符串缓冲区。
This is pretty old school, I use it in large loops to avoid instantiating another string buffer.
如果您使用的是 Qt,则可以使用以下代码:
另外,不要忘记添加
#include
。If you are using Qt, you can use this code:
Also, do not forget to add
#include <QLocale>
.正确的解决方案是
您不能使用 std::fixed - 它仅适用于浮点
Right solution is
YOU MUST NOT USE std::fixed - it's only for floating point
根据上面的答案,我最终得到了这段代码:
based on the answers above, I ended up with this code:
我找到了解决方案!只需将其复制到您的函数之一,该函数是用静态函数编写的。
以下是这些代码的结果:
I found the solution! just copy this to one of your function, this function is written in static function.
Here is the result of those code:
我见过很多这样做的方法,反转字符串(两次!),使用 setlocale(有时有效有时无效)
这是一个模板解决方案,然后我添加显式专业化。这适用于 char*、wchar*、string 和 wstring。
我在这里不从数字转换为字符串格式,我强烈推荐 to_string 和 to_wstring 它们比 'C' 函数(如 _itoa 等)快得多...
}
我已经测试了多达 1,000 个空格(当然有更大的缓冲区)
I have seen so many ways of doing this, reversing the string(Twice!), using setlocale(sometimes works sometimes not)
This is a template solution, I then add explicit specializations. This works for char*, wchar*, string and wstring.
I dont translate from numeric to string format here, I highly recommend to_string and to_wstring they are way faster than the 'C' functions such as _itoa etc...
}
I have tested up to 1,000 spaces(With a larger buffer of course)
这是获得您所要求的内容的非常简单的方法。您将需要一个 long long 来处理 result3 201+ 十亿。函数 formatWithCommas() 接受一个 long long 并返回一个格式化字符串,每隔三个小数位有一个逗号。使用标准字符串库中的字符串方法 to_string() 将数字转换为字符串。然后使用 string.length() 获取数字字符串的长度。设置一个 for 循环,从字符串长度减三开始。使用字符串库 insert() 中的另一个函数,在递减 3 时,每隔三个位置放置一个逗号,i -= 3。请注意,我使用字符串“,”而不是字符“,”。如果不更改数据类型,则只需要两个参数,即索引和在本例中的子字符串。如果更改数据类型,则需要使用第三个参数来说明要从给定索引开始放置多少个字符。下面是一个示例,str.insert(i, ",") 或 str.insert(i, ',', 1)。循环的条件部分 i > 0 将阻止循环在少于四个字符的字符串上运行,因为 str.length() -3 必须至少为 4,才能在 i > 时使 i 等于 1。 0 为真实陈述。
如果您需要使用可能的负数,您可以在 for 循环之前设置一个 bool 标志并操作索引零,并在正确放置逗号之后插入负号 - 返回格式化的数字字符串。
Here is a very simple way to get what you are asking for. You will need a long long to handle result3 201+ billion. The function formatWithCommas() takes in a long long and returns a formatted string with commas at every third decimal place. Use string method to_string() from the standard string library to convert your number to a string. Then use string.length() to get the length of your numeric string. Setup a for loop that starts at the length of your string minus three. Use another function from the string library insert() to place a comma at every third position as you decrement by three, i -= 3. Notice that I use a string "," instead of a character ','. If you don't change datatypes you only need two arguments, the index and in this case a sub-string. If you change datatypes you will need to use a third argument to state how many characters you want to place starting at the given index. Here is an example, str.insert(i, ",") or str.insert(i, ',', 1). The conditional section of your loop i > 0 will prevent the loop from running on a string with less than four characters as str.length() -3 must be at least four to start with making i equal to one for i > 0 to be a true statement.
If you need to work with possibly negative numbers you can set a bool flag and manipulate index zero before the for loop and insert the negative symbol - back after the commas have been correctly placed before returning the formatted numeric string.
提出另一个解决方案:
Make another solution:
根据上面 Jacob 的回答...
这是一个 Windows 解决方案。
执行结果如下。
Based on Jacob's answer above...
This is a Windows solution.
The execution result is as follows.
受到 @carljalal 答案的启发,我使用反向迭代器找到了一个类似但不同的答案。可能效率较低,但更紧凑:
注意,有 使用
.base()
时有些谨慎,但对于我尝试的输入来说,一切似乎都很好。上面处理任何长度的数字字符串,无论前面有或没有负号,但不处理小数。另请注意,std::make_reverse_iterator
需要 c ++14 或更高版本。一些示例输入和输出:
演示
Inspired by @carljalal's answer, I found a similar-but-different answer using reverse iterators. Probably less efficient, but a bit more compact:
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 thatstd::make_reverse_iterator
requires c++14 or later.Some sample inputs and outputs:
Demonstration
为了使其更加灵活,您可以使用自定义的千位分隔符和分组字符串构建构面。
这样你就可以在运行时设置它。
To make it more flexible, you could construct the facet with a custom thousands sep and grouping string.
This way you can set it at runtime.