C++ 小数点和千点不工作

C++ 小数点和千点不工作,c++,locale,comma,period,decimal-point,C++,Locale,Comma,Period,Decimal Point,似乎被我的流完全忽略了 我要做的是在中使用句点表示我的千次sep,使用逗号表示我的小数点。所以我重写了,但它被忽略了:( struct punct\u facet:public money punct{ char_type do_decimal_point()常量{return',';} char_type do_数千_sep()常量{return'.;} }; int main() { istringstream USCurrency(“1234.56-1234.56 1.234,56-1.2

似乎被我的流完全忽略了

我要做的是在中使用句点表示我的
千次sep
,使用逗号表示我的
小数点。所以我重写了,但它被忽略了:(

struct punct\u facet:public money punct{
char_type do_decimal_point()常量{return',';}
char_type do_数千_sep()常量{return'.;}
};
int main()
{
istringstream USCurrency(“1234.56-1234.56 1.234,56-1.234,56”);
USCurrency.imbue(locale(locale(“en-US”),新的punct_facet));
int指数=0;
长双值;
做{
数值=0.0;
USCurrency>>获得金钱(价值,真实);

cout这个解决方案实际上只是对问题的一种解释

复制构造函数和赋值运算符都被
moneypunct
实现删除。这就为构造
punct\u facet
留下了两个不好的选项:

  • 复制
    punct\u facet
    中的所有
    moneypunct
    成员,并调用
    punct\u facet
    构造函数中的所有
    moneypunct
    虚拟函数对其进行初始化。这有一个明显的缺点,即
    punct\u facet
    对象的脂肪是它应该的两倍,并且它的构造函数运行时间比严格的构造函数长非常必要
  • 使用指针和特定于编译器的对象布局知识来实现从
    moneypunct
    punct\u facet
    的复制构造。这有一个明显的缺点,即不跨平台,故意忽略标准实现的设计
  • 对于这个答案,我选择了错误的选项2,因为除了:
    “C”
    ,或
    “POSIX”
    之外,对于任何构造参数,
    moneypunct
    的实现已经是特定于编译器的,并且因为存在针对已删除的
    moneypunct
    复制构造函数和赋值运算符的错误。(顺便说一句,如果
    moneypunct
    构造参数也被调整为选项2,但它在Clang 3.6.0中不起作用。)希望微软能很快为该漏洞提供一个功能更强大的解决方案,我们不必使用任何一个坏选项

    因此,如果
    punct\u facet
    是这样实现的:

    template <typename T>
    class punct_facet : public T {
    private:
        void Init(const T* money){
            const auto vTablePtrSize = sizeof(void*);
    
            memcpy(reinterpret_cast<char*>(this) + vTablePtrSize, reinterpret_cast<const char*>(money) + vTablePtrSize, sizeof(T) - vTablePtrSize);
        }
    protected:
        typename T::char_type do_decimal_point() const {
            return typename T::char_type(',');
        }
    
        typename T::char_type do_thousands_sep() const {
            return typename T::char_type('.');
        }
    public:
        punct_facet(){
            Init(&use_facet<T>(cout.getloc()));
        }
    
        punct_facet(const T* money){
            Init(money);
        }
    };
    
    要使用自定义构造函数,只需将
    imdue
    语句更改为:

    USCurrency.imbue(locale(locale("en-US"), new punct_facet<moneypunct<char, true>>()));
    
    USCurrency.imbue(locale(locale("en-US"), new punct_facet<moneypunct<char, true>>(&use_facet<moneypunct<char, true>>(locale("en-US")))));
    
    USCurrency.imbue(locale(locale)(“en-US”)、新的点阵面(&use_-facet(locale)(“en-US”));
    
    默认构造函数更可取,因为模板类型和构造函数参数之间的差异可能导致某些不良行为


    需要注意的是,您的
    USCurrency
    没有使用国际货币格式,因此不需要使用
    moneypunct
    moneypunct
    可以正常工作。只要记住在所有地方都更改它,因为
    punct\u facet
    的模板参数与
    get\u money
    中使用的参数之间存在差异>将再次导致您看到的意外行为。

    get\u money
    使用
    moneypunct
    facet,而不是
    numpunct
    @IgorTandetnik我不得不说这听起来很有希望,但在我的示例中,当我将
    numpunct
    更改为
    moneypunct
    时,我只得到:
    1:1
    作为输出。我的自定义
    moneypunct
    它还需要我调用
    get_money(value,true)
    ,然后我得到原始输出。无论哪种方式,它似乎都不能解决问题。为什么您只希望
    1:123
    ?@0x499602D2 money应该在
    en-US
    中计算到小数点后两位。(这就是为什么我实际得到的最后陈述是
    123
    USCurrency.imbue(locale(locale("en-US"), new punct_facet<moneypunct<char, true>>(&use_facet<moneypunct<char, true>>(locale("en-US")))));