【发布时间】:2010-10-11 07:59:47
【问题描述】:
我发现我一直使用的 strtod 方法存在问题。 首先它不理解非点小数分隔符,所以我不得不使用这个:
std::replace(sSource.begin(), sSource.end(), getDecimalSeparator(), '.');
但是没有,我发现了另一个问题,但还没有找到解决方法。如果值为负数且千位分隔符为点(“.”),则 strtod 返回 0 且 _EndPtr 指向字符串的开头:
// PRECONDITIONS:
// * digit grouping symbol (thousands separator) = "."
// * decimal symbol = ","
// * digital grouping = "123.456.789"
// * negative sign symbol = "-"
// * negative number format = "- 1,1"
// * OS WinXP SP2
// * the rest doesn't matter
double parse(const char* cszValue, char** szStop)
{
// NOTE: error handling code has been removed to simplify the sample
return strtod(sSource.c_str(), szStop);
}
//...
char* szStop = NULL;
double dVal = 0.0;
dVal = parse("123.45", &szStop); // works!
// All the next DON'T WORK!
dVal = parse("123,45", &szStop); // dVal == 123.0 szStop == ",45"
dVal = parse("- 123.45", &szStop); // dVal == 0.0 szStop == "- 123.45"
// the same for "- 123,45"
dVal = parse("1.123.45", &szStop); // dVal == 1.123 szStop == ".45"
// the same for "1.123,45"
dVal = parse("1 123.45", &szStop); // dVal == 1 szStop == " 123.45"
// the same for "1 123,45"
dVal = parse("- 1 123,45", &szStop); // dVal == 0 szStop == start of the string
// the same for "- 1 123.45", "- 1.123,45", "- 1.123.45"
有问题:
我做错了什么?(已回答)
如果根据本地设置格式化小数分隔符,为什么 strtod 会失败?(已回答)
即使我将当前的小数点分隔符替换为点(“.”)并删除所有千位分隔符,如何解析负值?检测到负号,将其删除,将值解析为正数,然后反转负号?
【问题讨论】:
-
为什么转了,和.? , 是千位分隔符,并且 .是小数。
-
一些语言环境(如西班牙语)正好相反:“。”是千位分隔符,“,”是小数。
-
有多少程序员不知道语言环境和语言的含义,这总是令人惊讶 ;-)