“8”的 int.Parse失败了。 int.Parse 总是需要 CultureInfo.InvariantCulture?

发布于 2024-08-30 09:03:27 字数 1745 浏览 5 评论 0 原文

我们开发了一种既定的软件,可以在除一台计算机之外的所有已知计算机上正常运行。问题是解析以“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

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

We develop an established software which works fine on all known computers except one. The problem is to parse strings that begin with "8". It seems like "8" in the beginning of a string is a reserved character.

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

The problem is solved using int.Parse("8", CultureInfo.InvariantCulture). However, it would be nice to know the source of the problem.

Question: Why do we get this behaviour of "8" if we don't specify invariant culture?


Additional information:

I did send a small program to my client achieve the result above:

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

Update

I stumbled across this link, a bug in the microsoft connect database:

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

It seems like there's an issue with similiar symptoms, but no real root cause. If anyone could elaborate on this I would be grateful!

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

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

发布评论

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

评论(1

划一舟意中人 2024-09-06 09:03:27

对于 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

您可以明确地说您正在使用接受 NumberStylesParse 重载来解析整数而不是货币> 枚举。

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,顺便说一句,下次您需要向问题添加更多信息时,您应该对其进行编辑,而不是在答案中提供。

For the sv-SE culture 8 represents CurrencyNegativePattern and that's why you're getting the error you describe.

You can check this by running the following example:

var ci = new CultureInfo("sv-SE");

var nfi = (NumberFormatInfo)ci.GetFormat(typeof(NumberFormatInfo));

Console.WriteLine(nfi.CurrencyNegativePattern);
Console.WriteLine(nfi.CurrencyPositivePattern);

This will output:

// 8
// 3

You can explicitly say that you are parsing an integer and not a currency by using the Parse overload that accepts a NumberStyles enumeration.

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

This time since you are specifying that you're parsing an integer no error will occur.


However, IIRC the Int32.Parse should interpret the input as an integer by default, so why you're getting to the error with that sample code is beyond me.


Update:

From the information you recently added it seems that you should make sure that the problem is not external. This is, if the user for example changed the positive sign setting of the windows locale to 8 it would be normal and make perfect sense for you to get the error you are obtaining. It would be just like setting the + as the positive sign and then trying to parse it:

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

nfi.PositiveSign = "+";

Int32.Parse("+", nfi); // This will throw

Ask the user for it's locale registry settings like indicated in the Connect issue and check that they are what you would expect.

Side note: Welcome to SO and by the way next time you need to add further information to your question you should edit it instead of providing it in an answer.

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