2
votes

I'm writing code with german culture settings

Nevertheless I would like to force the user to use the point as a decimal separator.

My piece of test code outputs the wrong value.

How do I detect the "wrong" comma ?(throw an exception)

string nok_str = "14,9";
string ok_str = "14.9";

double nok_Var1 = double.Parse(nok_str, CultureInfo.InvariantCulture.NumberFormat); // outputs 149.0
double nok_Var2 =Convert.ToDouble(nok_str, CultureInfo.InvariantCulture.NumberFormat); // outputs 149.0
3
, is called a comma. The colon is a :.kennytm
You don't have to add "NumberFormat" just CultureInfo.InvariantCulture would be sufficient.Paweł Dyda
in the comma example, what would be the thousandths separator?Fosco
@Fosco: The dot, obviously. Just check Console.WriteLine(CultureInfo.GetCultureInfo("de-DE").NumberFormat.NumberGroupSeparator);Timwi

3 Answers

3
votes

First off, and please forgive me, I’d like to question your design decision:

How is this enhancing the user experience? The application should rather try to accept all unambiguous user input, not reject theoretically sound input.

That said, a number such as “19,2” will be interpreted, with an invariant culture, as having a thousands separator (which is simply discarded). This is why your code silently produces bad values. If you want to explicitly forbid this input, the easiest way to achieve this is an explicit test:

if (nok_str.Contains(","))
    throw new FormatException(…);

As an alternative, you can try modifying the NumberFormatInfo.NumberGroupSeparator property of a custom NumberFormatInfo object that you pass to the Parse method.

2
votes

Basically the default is to include AllowThousands in the number style. If you specify the number style you want, you can prohibit this:

using System;
using System.Globalization;

class Test
{
    static void Main(string[] args)
    {
        string text = "19,2";
        double value;
        bool valid = double.TryParse(text, NumberStyles.Float,
                                     CultureInfo.InvariantCulture,
                                     out value);
        Console.WriteLine(valid); // Prints false
    }
}

Note that NumberStyles.Float is a composite style for AllowLeadingWhite, AllowTrailingWhite, AllowLeadingSign, AllowDecimalPoint, and AllowExponent - but not AllowThousands.

0
votes

I am not sure what is the source of your input.

If it comes from user it also depends... If it is GUI application, you may think of restricting the input to certain possible keys, excluding comma. If it is a console app, you can try regular expressions to pre-validate input strings.

If it comes from various sources (i.e. web service) maybe simply brute-force string replace will do the trick?

Last, but not least: there are reasons for parsing to be culture-sensitive and if I were you, I would encourage users to enter valid regional number format instead forcing them to provide incorrect one.