一个普遍的国际问题是将以字符串表示的双精度值进行转换。这个问题在许多领域都有所体现。
从 CSV 文件开始,它们可能被称为
comma separated
或者
character separated
有时候它们被存储为这样的形式。
1.2,3.4
5.6,6.4
在英语区域或
1,2;3,4
5,6;6,4
在德国地区等国家,大多数std::方法是与语言环境有关的。因此,在德国,他们会将"1,2"读作1.2并将其写回为"1,2",但在英文操作系统中,它将将"1,2"读作1并将其写回为"1"。
由于语言环境是应用程序的全局状态,将其切换到不同的设置并不是一个好主意。当我需要在英文机器上读取德文CSV文件或反之亦然时,这里就会出现一些问题。
编写能够在所有机器上表现相同的代码也很困难。C++流允许每个流设置语言环境。
class Punctation : public numpunct<wchar_t>
{
public:
typedef wchar_t char_type;
typedef std::wstring string_type;
explicit Punctation(const wchar_t& decimalPoint, std::size_t r = 0) :
decimalPoint_(decimalPoint), numpunct<wchar_t>(r)
{
}
Punctation(const Punctation& rhs) :
decimalPoint_(rhs.decimalPoint_)
{
}
protected:
virtual ~Punctation()
{
};
virtual wchar_t do_decimal_point() const
{
return decimalPoint_;
}
private:
Punctation& operator=(const Punctation& rhs);
const wchar_t decimalPoint_;
};
...
std::locale newloc(std::locale::classic(), new Punctation(L','));
stream.imbue(newloc);
使用此方法,您可以使用std :: C的行为初始化流,并仅替换小数点。这使我能够忽略可能会对其产生影响的千位分隔符。
德文1000.12可能成为“1.000,12”;或者在英语中,“1,000.12”将导致完全混乱。即使将“,”替换为“.”也无济于事。
如果我必须使用 atof
和朋友
const char decimal_point = *(localeconv()->decimal_point);
为了优化我的行为。
因为国际双重行为需要大量的东西,甚至我的Visual Studio也会遇到问题,因为德语版本想要将8.0作为版本写入vcproj文件中,而英语版本则想将其更改为8.0,这绝对是一种偶然事件,因为在XML中,它被定义为全世界所有国家的8.0。
所以我只是想简单描述一下这个问题,并寻求我可能忽略的方面。以下是我所知道的内容:
- 小数点取决于本地设置
- 千位分隔符取决于本地设置
- 指数取决于本地设置
// German English Also known
// decimal point , .
// exponent e/E e/E d/D
// thousand sep . ,
哪个国家使用哪种设置?也许你可以给我一些迄今为止我没有的有趣例子。