为什么 System.Convert("0") 在某些系统上会抛出 FormatException?

发布于 2024-10-08 02:54:54 字数 1094 浏览 11 评论 0 原文

该代码是在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)

The code is compiled in VS2008 targeting .NET3.5. This is not reproducible on my system. I suspect some sort of localization setting is at play but I don't know much about that.

All other valid numbers seem to work fine. The bug is illustrated with this code (which causes the same exception but is not the production code):

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);
        }
    }
}

At the command line, input of "0" crashes the app on at least one system I have encountered.

Stack trace from user's 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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

路还长,别太狂 2024-10-15 02:54:54

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

参考问题在这里< /a>.

I remember this problem from a question a while back. The Parse() methods are affected by the user overrides in the Control Panel + Region and Language applet. IIRC, it is especially sensitive to the "Negative sign symbol" setting. Ask your user to correct the settings there.

The reference question is here.

固执像三岁 2024-10-15 02:54:54

如果您的问题与当前区域性有关,请尝试使用不变区域性转换为 Double:

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

If your problem is related to current culture, try converting to Double using Invariant Culture:

Convert.ToDouble("0", System.Globalization.CultureInfo.InvariantCulture);
屋檐 2024-10-15 02:54:54

很容易证明这不是代码(或 CultureInfo)的原因,我可以证明对于 .NET 中的所有区域性,字符串“0”可以正确转换为双精度。

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();

它只输出一个“结束”。

It's quite easy to prove that it's not because of the code(or the CultureInfo), I can prove that for all cultures in .NET, a string "0" can be converted to double correctly.

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();

It outputs nothing but an "end".

以可爱出名 2024-10-15 02:54:54

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

It might be related to culture settings. As I know in some culture settings you should type in 0.0 to be able to convert to double

ˉ厌 2024-10-15 02:54:54

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

当然,当您输入任何非数字时,它会崩溃。这意味着如果您输入空字符串(换句话说,只需按 Enter 键),它将崩溃。我想这就是你所经历的。

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

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

I don't think it does crash when you input 0.

It will, of course, crash when you input anything that is not a number. This means that it will crash if you input an empty string (in other words, just push enter). I imagine this is what you are experiencing.

You code would work (for only numbers) if you change it to this:

string str = "";
do
{
    str = Console.ReadLine();
    if(!string.IsNullOrEmpty(str))
        Console.WriteLine("\t\"{0}\"", Convert.ToDouble(str));
}
while (str != "");
追风人 2024-10-15 02:54:54

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

The CurrentCulture CultureInfo instance is probably to blame. Convert.ToDouble call, after all, simply returns the result of Double.Parse. This, as documented, uses the current culture's NumberFormatInfo to figure things out.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文