如何安全正确地将数字从用户输入转换为double?

时间:2012-01-05 03:38:04

标签: c# double user-input cultureinfo

这基本上是CultureInfo问题。形式上,在我的国家,小数点分隔符是逗号(,),千位分隔符是点(。)。然而,在实践中,这仅供会计师和勤奋的人使用。通常人们从不使用千位分隔符,并且它们可以互换地使用逗号和点作为小数分隔符。我已经看到这是一个问题,即使在我从其他人那里收到的一些Excel电子表格中,Excel没有将点识别为十进制分隔符,而是将字段格式化为字符串,而不是数字。

到目前为止,我的“解决方案”只是用点替换用户输入中的所有逗号,然后使用InvariantCulture解析双精度,如下所示:

string userInput;
...
userInput = userInput.Replace(',', '.');
double result;
double.TryParse(userInput, NumberStyles.Float, CultureInfo.InvariantCulture, out result);

当有人真正进入千位分隔符时,这显然会失败,这在我看来更像是一个黑客而不是一个真正的解决方案。那么,除了制作我自己的双打解析器之外,有没有更简洁的方法来处理这个问题?

2 个答案:

答案 0 :(得分:2)

如果您使用ASP.Net,您可以使用AjaxControlToolkit FilteredTextBox,您也可以使用regular expressions和模式匹配来完成任务。尝试获得标准输入几乎总是比尝试处理每个可能的人类输入变量更好。

其他一些链接:
MaskedTextBox
WPF Tools FilteredTextBox

答案 1 :(得分:1)

如果有规则可以最终确定它们的含义,那么您可以编写逻辑代码。但是,有了这个问题,在每种情况下都无法知道意图:

1,001 === 1.001 or 1001

此外,即使任何“更好”的逻辑可能会假设像“1,01”这样的数字是明确的,这样的条目可能是“1,001”的错字。这种可能性取决于您收集的数据类型。

如果人们很少使用千位分隔符,那么您现有的逻辑似乎很好。但是,如果你想100%确定意图,唯一可以肯定的方法是询问他们在这种情况下的含义。例如。如果有人输入1,0011.001然后验证失败,但将其重新编码为“1,001.0”(如果处理货币则为.00)以消除歧义,迫使他们重新确认。

在实践中,由于人们并没有真正使用千位分隔符,因此您可能会因为这种充分的谨慎而造成更多的弊大于利。我坚持你所得到的。