【问题标题】:Why does System.Convert("0") throw a FormatException on some systems?为什么 System.Convert("0") 在某些系统上会抛出 FormatException?
【发布时间】:2010-12-16 14:21:23
【问题描述】:

代码在 VS2008 中针对 .NET3.5 编译。这在我的系统上无法重现。我怀疑某种本地化设置在起作用,但我对此了解不多。

所有其他有效数字似乎都可以正常工作。此代码说明了该错误(导致相同的异常但不是生产代码):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "";
            do
            {
                str = Console.ReadLine();
                Console.WriteLine("\t\"{0}\"", Convert.ToDouble(str));
            }
            while (str != null);
        }
    }
}

在命令行中,输入“0”会使应用程序在我遇到的至少一个系统上崩溃。

来自用户 PC 的堆栈跟踪:

System.FormatException: Input string was not in a correct format.
   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseDouble(String value, NumberStyles options, NumberFormatInfo numfmt)
   at System.Double.Parse(String s, NumberStyles style, NumberFormatInfo info)
   at System.Convert.ToDouble(String value)

【问题讨论】:

  • 崩溃是什么意思?您没有收到任何错误消息或任何类型的堆栈跟踪?
  • 您盲目地将控制台输入转换为双精度。您是否尝试过首先使用Double.TryParse() 验证其编号?
  • Crash 是指未正确处理的异常。我得到了堆栈跟踪,但请记住,这是用户的 PC,我无法在我的机器上重现该问题。
  • @pomeroy,什么堆栈跟踪?什么例外?在什么输入上?在什么地区?
  • 也许有人只是对您的用户进行了恶作剧,并将他的 0 键重新映射到角色 O

标签: c# crash formatexception


【解决方案1】:

我从不久前的一个问题中记住了这个问题。 Parse() 方法受控制面板 + 区域和语言小程序中的用户覆盖的影响。 IIRC,它对“负号符号”设置特别敏感。要求您的用户更正那里的设置。

参考问题is here

【讨论】:

    【解决方案2】:

    如果您的问题与当前文化有关,请尝试使用 Invariant Culture 转换为 Double:

    Convert.ToDouble("0", System.Globalization.CultureInfo.InvariantCulture);
    

    【讨论】:

      【解决方案3】:

      很容易证明不是因为代码(或CultureInfo),我可以证明对于.NET中的所有文化,字符串“0”都可以正确转换为double。

      string inputNumber = "0";
      foreach (var culture in CultureInfo.GetCultures(CultureTypes.AllCultures))
      {
         try
         {
             double d = Convert.ToDouble(inputNumber, culture);
         }
         catch
         {
            Console.WriteLine(culture.Name);
         }
      }
      Console.WriteLine("end");
      Console.Read();
      

      它只输出一个“结束”。

      【讨论】:

      • 有趣。然而,崩溃无疑是由 Convert.ToDouble 方法输入“0”引起的。有什么想法吗?
      • @pomeroy:我认为你可以将str = Console.ReadLine(); 更改为str = "0"; 并再次尝试查看应用是否仍然崩溃。
      • 已确认:Convert.ToDouble("0") 导致 FormatException。
      【解决方案4】:

      这可能与文化设置有关。据我所知,在某些文化设置中,您应该输入 0.0 才能转换为双精度

      【讨论】:

        【解决方案5】:

        我认为输入0 时它不会崩溃。

        当您输入任何不是数字的内容时,它当然会崩溃。这意味着如果您输入一个空字符串(换句话说,只需按回车键),它将崩溃。我想这就是你正在经历的。

        如果您将其更改为以下代码,您的代码将起作用(仅适用于数字):

        string str = "";
        do
        {
            str = Console.ReadLine();
            if(!string.IsNullOrEmpty(str))
                Console.WriteLine("\t\"{0}\"", Convert.ToDouble(str));
        }
        while (str != "");
        

        【讨论】:

        • 多么居高临下啊。显然我没有拒绝你投票的名声,但我希望我这样做。
        • 我不认为他居高临下。您的例程不进行任何类型的验证,您只是说我们应该“相信”用户确实输入了一个有效数字,即使考虑到抛出的异常类型,这似乎并没有任何意义。抱歉,但如果出现问题,它会出现问题 - 您的代码不会做任何事情来避免这种情况。
        • 你们都没有阅读这个问题。该例程不是导致此崩溃的生产代码,该例程已被证明可以隔离用户 PC 上的问题。
        • @pomeroy:我并没有试图居高临下。对不起让你不高兴了。当您输入任何不是数字的内容时,您的代码将崩溃。循环的退出条件要求您输入不是数字的内容,因此每当您尝试退出时它都会崩溃。
        • 他没有居高临下。
        【解决方案6】:

        CurrentCulture CultureInfo 实例可能是罪魁祸首。 Convert.ToDouble调用毕竟只是返回Double.Parse的结果。正如所记录的,这使用当前文化的 NumberFormatInfo 来解决问题。

        【讨论】:

        • 是的,这也是我的想法。不幸的是,这本身并不是一个答案。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-03
        • 2015-04-24
        • 2014-12-12
        • 2013-07-12
        • 1970-01-01
        相关资源
        最近更新 更多