【问题标题】:Convert.ToDecimal from input string ignores dots but accepts comma [duplicate]输入字符串中的 Convert.ToDecimal 忽略点但接受逗号 [重复]
【发布时间】:2019-09-02 08:01:23
【问题描述】:

我有这么一小段代码:

using System;
using System.Globalization;

namespace project
{
    class conditionalStatements
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Enter a number greater than 45.2");
            string answer = Console.ReadLine();
            decimal answer_decimal = Convert.ToDecimal(answer);
            // decimal answer_decimal = Decimal.Parse(answer);
            decimal compareValue = 45.2m;

            Console.WriteLine(answer_decimal);
            //prints 452

            if(Decimal.Compare(answer_decimal, compareValue) > 0){
                // stuff
            }
            else{
                // should enter here
            }
        }
    }
 }

问题在于,由于Convert.ToDecimal()Decimal.Parse() 方法都忽略了十进制值的点表示法(或者至少这是发生在我身上的事情),所以数字被解释为452 而不是45.2。无论我输入多少点。事实上,如果我要进入:

45......2

转换后的值仍将转换为452仅当我使用逗号时,转换后的数字会被正确解释为45.2,并且我可以输入else 条件。

我没有更改NumberFormatInfo.CurrencyDecimalSeparator。我将其保留为默认值'.'

【问题讨论】:

  • 线程与什么文化相关联?
  • 与您当前问题无关的建议。切勿尝试在用户输入上使用 Convert.ToXXXX。如果用户键入无效数字,您的代码将引发异常。在这些情况下,请始终使用 decimal.TryParse

标签: c# .net parsing decimal decimal-point


【解决方案1】:

使用将点作为小数分隔符的给定文化将输入字符串转换为十进制:

decimal answer_decimal = Convert.ToDecimal(answer, new CultureInfo("en-US"));

【讨论】:

  • 问题指出小数点分隔符(至少对于货币而言)已经是'.'
  • 这解决了点的问题。但是,如果我想同时使用两者呢?因为在这种情况下,现在逗号也会出现同样的问题。就没有办法同时接受他们吗?非常感谢您的帮助:)
【解决方案2】:

你可以试试下面的代码:

decimal answer_decimal; 
while(!decimal.TryParse(answer, out answer_decimal)){
    Console.WriteLine("Value entered could not be converted.");
}
decimal compareValue = 45.2m;

        Console.WriteLine(answer_decimal);
        //prints 452

        if(Decimal.Compare(answer_decimal, compareValue) > 0){
            // stuff
        }
        else{
            // should enter here
        }

这样可以防止程序在无法转换时崩溃。 如果你想使用特定的文化,你可以通过使用 decimal.TryParse 的重载来实现,如下所示:

decimal.TryParse(answer, System.Globalization.NumberStyles.Any, new System.Globalization.CultureInfo("EN-us"), out answer_decimal);

【讨论】:

    【解决方案3】:

    你的文化是达里语吗?

    我认为适用的NumberFormatInfo propertyNumberDecimalSeparator,而不是CurrencyDecimalSeparator。直接或通过Convert.ToDecimal() 调用的decimal.Parse() 不知道货币是被解析的内容,除非传递了带有*Currency* 标志之一的NumberStyles 值。

    当调用不接受NumberStyles 参数的decimal.Parse() 重载时,它默认为NumberStyles.Number。这种复合风格包括NumberStyles.AllowDecimalPoint 风格,其状态的文档(强调我的)......

    如果NumberStyles 值包含AllowCurrencySymbol 标志并且解析的字符串包含货币符号,则小数分隔符由CurrencyDecimalSeparator 属性确定。 否则,小数分隔符由NumberDecimalSeparator 属性确定。

    现在,实际上是否有任何文化对数字和货币使用不同的小数分隔符?让我们找出来......

    CultureInfo.GetCultures(CultureTypes.AllCultures)
        .Where(culture => culture.NumberFormat.CurrencyDecimalSeparator != culture.NumberFormat.NumberDecimalSeparator);
    

    在产生少量文化的 .NET Framework v4.7.2 上...

    fr-CH
    kea
    kea-CV
    mr
    mr-IN
    prs
    prs-AF
    pt-CV
    

    调整 LINQ 查询以解决您看到的特定行为(货币小数点分隔符为 ".",数字小数点分隔符为 ",",数字组分隔符为 ".")...

    CultureInfo.GetCultures(CultureTypes.AllCultures)
        .Where(culture => culture.NumberFormat.CurrencyDecimalSeparator == ".")
        .Where(culture => culture.NumberFormat.NumberDecimalSeparator == ",")
        .Where(culture => culture.NumberFormat.NumberGroupSeparator == ".");
    

    ...将其缩小到两种达里文化...

    prs
    prs-AF
    

    果然,如果我事先将我的文化改为达里语......

    CultureInfo.CurrentCulture = new CultureInfo("prs");
    

    ...在我的系统上,您的代码的行为与您描述的完全一样。如果您不想使用文化的分隔符,那么解决方案当然是在系统、线程或方法级别指定具有您想要的分隔符的特定或自定义文化。 p>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-23
      • 1970-01-01
      • 2021-08-24
      • 1970-01-01
      • 2016-03-19
      • 1970-01-01
      • 2012-10-31
      • 2017-04-07
      相关资源
      最近更新 更多