代码之家  ›  专栏  ›  技术社区  ›  Vladimir Keleshev

字符串到float的通用解析

  •  5
  • Vladimir Keleshev  · 技术社区  · 15 年前

    在我的程序将要运行的环境中,人们在带有“,”和“.”分隔符的PC上随机使用“,”和“.”作为十进制分隔符。

    我试过这个:

        try
        {
            d = float.Parse(s);
        }
        catch
        {
            try
            {
                d = float.Parse(s.Replace(".", ","));
            }
            catch
            {
                d = float.Parse(s.Replace(",", "."));
            }
        }
    

    它不起作用。当我调试的时候发现它第一次解析的时候是错误的,“.”是一个千的分隔符(比如100000.000,0)。

    我是C#的noob,所以希望有比这更简单的解决方案:-)

    注意:人们将在具有不同分隔符设置的PC中同时使用“.”和“,”。

    3 回复  |  直到 13 年前
        1
  •  10
  •   Henk Holterman    15 年前

    string s = "1,23";  // or s = "1.23";
    
    s = s.Replace(',', '.');
    double d = double.Parse(s, CultureInfo.InvariantCulture);
    

    一般模式是:

        2
  •  2
  •   Panagiotis Kanavos    15 年前

    解析使用 CultureInfo.CurrentCulture ,反映用户通过区域设置选择的语言和数字格式。如果您的用户键入与他们为计算机选择的语言相对应的小数,那么使用普通的double.Parse()应该没有问题。如果用户将语言环境设置为希腊语并键入“8,5”,double.Parse(“8,5”)将返回8.5。如果他输入“8.5”,parse将返回85。

    如果用户将其区域设置设置为一个设置,然后开始使用错误的小数点,那么您将面临一个问题。没有一种干净的方法来分隔这些错误的条目,而不是真正想要输入分组字符的条目。当一个数字太短而不能包含分组字符时,可以向用户发出警告,并使用屏蔽或数字文本框来防止输入错误。

    CultureInfo.CurrentCulture.NumberFormat 财产。

    试图替换十进制和分组字符注定会失败,因为这取决于在编译时知道用户将使用哪种分隔符。如果您知道这一点,就可以使用用户头脑中的CultureInfo解析数字。不幸的是,User.Brain.CultureInfo还不是.NET框架的一部分:P

        3
  •  1
  •   Filip Ekberg    15 年前

    float ConvertToFloat(string value)
    {
        float result;
    
        var converted  = float.TryParse(value, out result);
    
        if (converted) return result;
    
        converted = float.TryParse(value.Replace(".", ",")), 
                                   out result);
    
        if (converted) return result;
    
        return float.NaN;
    }
    

    在这种情况下,以下将返回正确的数据

            Console.WriteLine(ConvertToFloat("10.10").ToString());
            Console.WriteLine(ConvertToFloat("11,0").ToString());
            Console.WriteLine(ConvertToFloat("12").ToString());
            Console.WriteLine(ConvertToFloat("1 . 10").ToString());
    

    退换商品

    10,1
    11
    12
    NaN
    

    float.TryParse(value,
                NumberStyles.Currency,
                CultureInfo.CurrentCulture,
                out result)
    

    Console.WriteLine(ConvertToFloat("10,10").ToString());
    Console.WriteLine(ConvertToFloat("11,0").ToString());
    Console.WriteLine(ConvertToFloat("12").ToString());
    Console.WriteLine(ConvertToFloat("1 . 10").ToString());
    Console.WriteLine(ConvertToFloat("100.000,1").ToString());
    

    10,1
    11
    12
    110
    100000,1
    

    因此,根据你对用户的“友好程度”,你总是可以替换最后一步,如果它不是一个数字,也可以尝试用这种方式转换它,否则它真的不是一个数字。

    它看起来像这样

    float ConvertToFloat(string value)
    {
        float result;
    
        var converted = float.TryParse(value,
                                        out result);
    
    
        if (converted) return result;
    
        converted = float.TryParse(value.Replace(".", ","),
                                    out result);
    
        if (converted) return result;
    
        converted = float.TryParse(value,
                                        NumberStyles.Currency,
                                        CultureInfo.CurrentCulture,
                                        out result);
    
        return converted ? result : float.NaN;
    }
    

    以下是

    Console.WriteLine(ConvertToFloat("10,10").ToString());
    Console.WriteLine(ConvertToFloat("11,0").ToString());
    Console.WriteLine(ConvertToFloat("12").ToString());
    Console.WriteLine(ConvertToFloat("1 . 10").ToString());
    Console.WriteLine(ConvertToFloat("100.000,1").ToString());
    Console.WriteLine(ConvertToFloat("asdf").ToString());
    

    退换商品

    10,1
    11
    12
    110
    100000,1
    NaN