C++ 不带stringstream的逗号分隔数字
因此,通常,如果我想在一些数字中插入与区域设置相关的分隔符,C++ 不带stringstream的逗号分隔数字,c++,locale,number-formatting,stringstream,separator,C++,Locale,Number Formatting,Stringstream,Separator,因此,通常,如果我想在一些数字中插入与区域设置相关的分隔符,foo,我会这样做: ostringstream out; out.imbue(locale("en-US")); out << foo; ostringstreamout; out.imbue(locale(“en-US”); 外面竖起一根管子。使用链接到的代码,然后输出到其中一个,然后从另一个读取 这是一个奇怪而扭曲的解决方案。但是,你必须使用区域设置,必须存储东西,不能使用stringstream,这种想法也很奇怪
foo
,我会这样做:
ostringstream out;
out.imbue(locale("en-US"));
out << foo;
ostringstreamout;
out.imbue(locale(“en-US”);
外面竖起一根管子。使用链接到的代码,然后输出到其中一个,然后从另一个读取
这是一个奇怪而扭曲的解决方案。但是,你必须使用区域设置,必须存储东西,不能使用stringstream
,这种想法也很奇怪。所以,他们给你奇怪的要求,他们得到奇怪的代码。< /P> < P>所以这个答案是C++对Jerry Coffin对这个问题的回答的蒸馏:< /P>
模板
如果poscommafmt(常数N、常数numpunct和fmt信息)启用{
const auto group=fmt_info.grouping();
自动posn=cbegin(组);
自动除数=静态施法(功率(10.0F,静态施法(*posn));
自动商=div(N,除数);
自动结果=到字符串(商.rem);
while(商.quot>0){
如果(下一个(posn)!=cend(集团)){
除数=静态施法(功率(10.0F,静态施法(*++posn));
}
商=div(商,除数);
结果=to_字符串(商.rem)+fmt_info.数千_sep()+结果;
}
返回结果;
}
模板
如果通信(常数N、常数numpunct和fmt信息)启用{
返回N<0?'-'+poscommafmt(-N,fmt_信息):poscommafmt(N,fmt_信息);
}
这自然会受到相同2的赞美否定问题的影响
这当然得益于C++的string
内存管理,也得益于传入特定numpunct
的能力,该语言不需要是当前的语言环境。例如,无论cout.getloc()==locale(“en-US”)
您都可以调用:commafmt(foo,use_facet(locale(“en-US”))
所以你想将一个数字转换成千分字符串,或者将一个字符串转换成千分字符串,还是只需要这样输出?@NathanOliver是的,显然我可以手动插入它们。但这并不适用于区域设置:(看起来你可以使用sprintf
而不是printf
。看起来这只是一个C功能。糟糕。不使用stringstream
是一个奇怪的要求。特别是如果你还必须处理区域设置。哈哈,我可以保证这不会让它通过审查:)@JonathanMee-然后你可以向他们寻求更好的方法来满足需求。:-)有时候,这是迫使愚蠢的决定得到应有的审查的最佳方式。我已经告诉了测试部门应该加入哪些测试用例来触发我知道存在的bug,但开发人员不承认。有时候,你必须破解的是组织,而不是代码。这可能是一个合理的建议。当编写一个单独的程序来解决这个问题时,你知道事情已经变得非常糟糕了。@JonathanMee-我可以问一下避免stringstream
的理由是什么吗?@JonathanMee-我想你没有回答所有的最后一个问题。您是否可以再试一次:编码标准是否说明了为什么“不使用流”?有人记得不使用流的理由吗?
template <typename T>
enable_if_t<is_integral_v<remove_reference_t<T>>, string> poscommafmt(const T N, const numpunct<char>& fmt_info) {
const auto group = fmt_info.grouping();
auto posn = cbegin(group);
auto divisor = static_cast<T>(pow(10.0F, static_cast<int>(*posn)));
auto quotient = div(N, divisor);
auto result = to_string(quotient.rem);
while(quotient.quot > 0) {
if(next(posn) != cend(group)) {
divisor = static_cast<T>(pow(10.0F, static_cast<int>(*++posn)));
}
quotient = div(quotient.quot, divisor);
result = to_string(quotient.rem) + fmt_info.thousands_sep() + result;
}
return result;
}
template <typename T>
enable_if_t<is_integral_v<remove_reference_t<T>>, string> commafmt(const T N, const numpunct<char>& fmt_info) {
return N < 0 ? '-' + poscommafmt(-N, fmt_info) : poscommafmt(N, fmt_info);
}