C++ boost locale +词法强制转换抛出异常

zzlelutf  于 2023-04-01  发布在  其他
关注(0)|答案(1)|浏览(112)
boost::locale::generator gen;   
std::locale loc = gen("de_DE.UTF-8");
std::locale::global(loc);

std::string s = "3,14";
double d = boost::lexical_cast<double>(s);
std::cout << d << std::endl;

为什么这段代码会抛出异常?Boost Locale不影响词法转换?
我想用逗号作为分隔符,而不是句点。

svujldwt

svujldwt1#

Boost Locale不适用于任何数字。您必须使用IO操纵器来告诉它。例如:

**一个

#include <boost/lexical_cast.hpp>
#include <boost/locale.hpp>
#include <iostream>

namespace as = boost::locale::as;

int main() {
    boost::locale::generator gen;
    auto de = gen("de_DE.utf8");
    // std::locale::global(de);

    std::cout.imbue(de);
    std::cin.imbue(de);

    std::cout << 134.45 << std::endl;
    std::cout << as::number << 134.45 << std::endl;
    std::cout << as::currency << 134.45 << std::endl;
}

图纸

134.45
134,45
134,45 €

所以,它的理由是,以下将工作:Live On Coliru

if (double punkt; is("123.45") >> punkt)
     std::cout << "Punkt " << punkt << "\n";
else std::cout << "Punkt failed\n";

if (double komma; is("123,45") >> komma)
     std::cout << "Komma " << komma << " (OOPS!)\n";
else std::cout << "Komma failed\n";

if (double nummer; is("123,45") >> as::number >> nummer)
     std::cout << "Nummer " << nummer << "\n";
else std::cout << "Nummer failed\n";

打印(注意OOPS情况):

Punkt 123,45 €
Komma 123,00 € (OOPS!)
Nummer 123,45 €

成功了吗?

即使你设置了全局语言环境,lexical_cast也不会接受操纵器。但是Boost Convert可以:

  • 最初的希望是看到boost::lexical_cast扩展到适用于更广泛的部署场景。然而,在与Kevlin Henney(boost::lexical_cast的作者)和Boost Developers论坛讨论后,大家一致认为所需的扩展与原始设计和boost::lexical_cast所体现的思想不兼容,因此需要一个具有更丰富接口和功能的新组件。这一决定导致了本文所述的Boost.Convert的开发。*

30年代的介绍:一个月三次

#include <boost/convert.hpp>
#include <boost/convert/stream.hpp>
#include <boost/locale.hpp>
#include <iostream>

namespace cnv = boost::cnv;

int main() {
    boost::locale::generator gen;
    std::locale::global(gen("de_DE.utf8"));

    cnv::cstream cnv;
    cnv(boost::locale::as::number);
    auto from_string = cnv::apply<double>(std::ref(cnv));
    auto to_string   = cnv::apply<std::string>(std::ref(cnv));

    std::cout << "Parsed "    << from_string("123,45") << "\n";
    std::cout << "Formatted " << to_string(123.45)     << "\n";
}

但是,词汇演员!

当然,使用lexical_cast Just Work(TM)非常方便,您可以引入一个轻量级的 Package 器类型:

一个月四个月

#include <boost/lexical_cast.hpp>
#include <boost/locale.hpp>
#include <iostream>

namespace as = boost::locale::as;

struct Number {
    double value_;
    Number(double init = {}) : value_(init) {}
    operator double() const { return value_; }

    friend std::istream& operator>>(std::istream& is, Number& num) {
        return is >> as::number >> num.value_ >> as::posix;
    }
    friend std::ostream& operator<<(std::ostream& os, Number const& num) {
        return os << as::number << num.value_ << as::posix;
    }
};

int main() {
    boost::locale::generator gen;
    std::locale::global(gen("de_DE.utf8"));

    std::cout << "Formatted: " << boost::lexical_cast<std::string>(Number{234.56}) << "\n";
    double parsed = boost::lexical_cast<Number>("345,67");
    std::cout << "Parsed: " << parsed << "\n";
}

图纸

Formatted: 234,56
Parsed: 345.67

请注意,您甚至可以将Number演化为一种词汇表类型,这样就不必为转换而 Package 它。

相关问题