【问题标题】:int.Parse of "8" fails. int.Parse always requires CultureInfo.InvariantCulture?“8”的 int.Parse 失败。 int.Parse 总是需要 CultureInfo.InvariantCulture?
【发布时间】:2010-04-27 09:26:05
【问题描述】:

我们开发了一种成熟的软件,可以在除一台以外的所有已知计算机上正常运行。问题是解析以“8”开头的字符串。 字符串开头的“8”似乎是保留字符。

Parsing:
int.Parse("8") -> Exception message: Input string was not in a correct format. 
int.Parse("80") -> 0
int.Parse("88") -> 8
int.Parse("8100") -> 100

CurrentCulture: sv-SE 
CurrentUICulture: en-US

使用 int.Parse("8", CultureInfo.InvariantCulture) 解决了问题。不过,如果知道问题的根源就好了。

问题:如果我们不指定不变的文化,为什么我们会得到这种“8”的行为?


其他信息:

我确实向我的客户发送了一个小程序,实现了上述结果:

    private int ParseInt(string s)
    {
        int parsedInt = -1000;
        try
        {
            parsedInt = int.Parse(s);

            textBoxMessage.Text = "Success: " + parsedInt;

        }
        catch (Exception ex)
        {
            textBoxMessage.Text =
                string.Format("Error parsing string: '{0}'", s) + Environment.NewLine +
                "Exception message: " + ex.Message;
        }

        textBoxMessage.Text += Environment.NewLine + Environment.NewLine +
            "CurrentCulture: " + Thread.CurrentThread.CurrentCulture.Name + "\r\n" +
            "CurrentUICulture: " + Thread.CurrentThread.CurrentUICulture.Name + "\r\n";
        return parsedInt;
    }

更新

我偶然发现了这个链接,这是 microsoft connect 数据库中的一个错误:

https://connect.microsoft.com/VisualStudio/feedback/details/253265/int32-parse-fails-to-convert-the-string-0-zero-on-some-systems

似乎存在类似症状的问题,但没有真正的根本原因。如果有人能详细说明这一点,我将不胜感激!

【问题讨论】:

    标签: c# .net parsing cultureinfo currentculture


    【解决方案1】:

    对于 sv-SE 文化,8 代表 CurrencyNegativePattern,这就是您收到您描述的错误的原因。

    您可以通过运行以下示例来检查这一点:

    var ci = new CultureInfo("sv-SE");
    
    var nfi = (NumberFormatInfo)ci.GetFormat(typeof(NumberFormatInfo));
    
    Console.WriteLine(nfi.CurrencyNegativePattern);
    Console.WriteLine(nfi.CurrencyPositivePattern);
    

    这将输出:

    // 8
    // 3
    

    您可以通过使用接受NumberStyles 枚举的Parse 重载明确表示您正在解析整数而不是货币。

    Int32.Parse("8", NumberStyles.Integer, new CultureInfo("sv-SE"));
    

    这一次,由于您指定解析整数,因此不会发生错误。


    但是,IIRC Int32.Parse 默认情况下应该将输入解释为整数,所以你为什么会遇到该示例代码的错误超出了我的理解。


    更新:

    从您最近添加的信息看来,您应该确保问题不是外部问题。也就是说,例如,如果用户将 Windows 语言环境的正号设置更改为 8,这将是正常的,并且对您获得所获得的错误非常有意义。这就像将+ 设置为正号,然后尝试解析它:

    var ci = new CultureInfo("sv-SE");
    var nfi = (NumberFormatInfo)ci.GetFormat(typeof(NumberFormatInfo));
    
    nfi.PositiveSign = "+";
    
    Int32.Parse("+", nfi); // This will throw
    

    向用户询问其区域设置注册表设置,如 Connect 问题中所示,并检查它们是否符合您的预期。

    旁注:欢迎来到 SO,顺便说一下,下次您需要向问题添加更多信息时,您应该编辑它而不是在答案中提供它。

    【讨论】:

    • 感谢旁注,我已经处理好了 :) 我之前已经检查了注册表中的值以了解他的语言环境设置,唯一的 8 个是 CurrencyNegativePattern 这对我没有帮助在我的机器上重现错误。你在这里肯定是正确的轨道 João。但是,这个问题很难,我也不确定微软是否知道问题的原因。你肯定会得到一个很大的提升,但这种行为仍然是一个谜。这就是为什么我不接受你的答案作为解决方案,即使我很感激你的努力!
    • 这个答案的开头对我来说似乎是错误的。 NumberFormatInfo.CurrencyNegativePatternNumberFormatInfo.CurrencyPositivePattern 中的值仅用作键 - 标识负号 (-)、货币符号的顺序以及将用于格式化/解析的数字本身。例如,'8' 作为CurrencyNegativePattern 的值意味着模式应该是'-n $'。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多