一个常见的国际问题是字符串中表示的双精度值的转换。这种东西在很多地方都可以找到。
从 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 . ,
哪个国家使用哪个设置?也许你可以给我添加一些我现在还没有的有趣的例子。