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