双重字符串转换和本地化

7

一个普遍的国际问题是将以字符串表示的双精度值进行转换。这个问题在许多领域都有所体现。

从 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        .            ,

哪个国家使用哪种设置?也许你可以给我一些迄今为止我没有的有趣例子。

http://en.wikipedia.org/wiki/Decimal_point#Examples_of_use - Pod
2个回答

2
不要使用atof(s)。它是strtod(s,0)的快速而不严谨的替代品,没有错误报告。(atoi()和strtol()同理。)
如果一个函数在遇到困难时被宣传为返回错误代码,你应该检查该代码,即使这些检查会使你的代码体积增加三倍,并让你的打字手指疼痛。因为如果你认为“这种情况不可能发生在我身上”,那么神一定会惩罚你的傲慢。(Henry Spencer,《C程序员十条戒律》第6条)

-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接