输入字符串格式不正确。

114

我刚接触C#,基本了解Java,但无法使这段代码正常运行。

这只是一个基本的计算器,但是当我运行程序时,VS2008会给出这个错误:

Calculator

我几乎做了相同的Java程序,使用JSwing也完美运行了。

这是C#的窗体:

Form

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace calculadorac
{
    public partial class Form1 : Form
    {

    int a, b, c;
    String resultado;

    public Form1()
    {
        InitializeComponent();
        a = Int32.Parse(textBox1.Text);
        b = Int32.Parse(textBox2.Text);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        add();
        result();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        substract();
        result();
    }

    private void button3_Click(object sender, EventArgs e)
    {
        clear();
    }

    private void add()
    {
        c = a + b;
        resultado = Convert.ToString(c);
    }

    private void substract()
    {
        c = a - b;
        resultado = Convert.ToString(c);
    }

    private void result()
    {
        label1.Text = resultado;
    }

    private void clear()
    {
        label1.Text = "";
        textBox1.Text = "";
        textBox2.Text = "";
    }
}

有什么问题可能会出现?有没有解决方法?

PS:我也尝试了其他方法

a = Convert.ToInt32(textBox1.text);
b = Convert.ToInt32(textBox2.text);

但它没有起作用。

9个回答

140

这个错误意味着你试图从中解析整数的字符串实际上并不包含有效的整数。

当表单创建时,文本框立即包含有效的整数非常不可能 - 这就是你获取整数值的地方。更合理的做法是在按钮点击事件中更新ab(就像在构造函数中一样)。此外,可以查看Int.TryParse方法 - 如果字符串可能并不包含整数,使用它会更加容易 - 它不会抛出异常,因此更容易从中恢复。


3
当试图将来自具有不同CultureInfo的用户的输入转换为double时,也可能会抛出此错误消息,因此您可以使用Convert.ToDouble(String,IFormatProvider)而不仅仅是Convert.ToDouble(String)。这很难调试,因为程序在您的系统上运行时将正常工作,但会在其某些用户处抛出错误,这就是为什么我在我的服务器上记录错误并快速找到问题的方法。 - vinsa

75

我遇到过完全相同的异常,但与解析数字输入无关。因此,这不是对OP问题的答案,但我认为分享这个知识是可以接受的。

我声明了一个字符串,并将其格式化以供JQTree使用,它需要花括号({})。您必须使用双花括号才能将其接受为格式正确的字符串:

string measurements = string.empty;
measurements += string.Format(@"
    {{label: 'Measurement Name: {0}',
        children: [
            {{label: 'Measured Value: {1}'}},
            {{label: 'Min: {2}'}},
            {{label: 'Max: {3}'}},
            {{label: 'Measured String: {4}'}},
            {{label: 'Expected String: {5}'}},
        ]
    }},",
    drv["MeasurementName"] == null ? "NULL" : drv["MeasurementName"],
    drv["MeasuredValue"] == null ? "NULL" : drv["MeasuredValue"],
    drv["Min"] == null ? "NULL" : drv["Min"],
    drv["Max"] == null ? "NULL" : drv["Max"],
    drv["MeasuredString"] == null ? "NULL" : drv["MeasuredString"],
    drv["ExpectedString"] == null ? "NULL" : drv["ExpectedString"]);

希望这能帮助那些发现这个问题但不解析数值数据的人。


3
这个答案怎么能得到66次点赞呢?它是关于如何解析C#中的整数的问题。 - nvoigt
3
问题是“输入的字符串格式不正确”。有66个人发现这个问题很有用,它也很相关。问题出在哪里? - Pogrindis
1
这是我第二次在谷歌搜索“输入字符串格式不正确”时回到这个答案。尝试点赞,但我在几年前第一次查看时已经点过了。 - Jarrod McGuire

23

如果您在文本字段中没有明确验证数字的话,在任何情况下最好使用

int result=0;
if(int.TryParse(textBox1.Text,out result))

如果结果是成功的,那么您可以继续进行计算。


14
通常情况下,result 不需要初始化。 - yazanpro

16

问题

出现错误的可能情况如下:

  1. 因为 textBox1.Text 只包含数字,但这个数字太大/太小

  2. 因为 textBox1.Text 包含:

    • a) 非数字(除开开头/结尾的空格、开头的 -)和/或
    • b) 应用于您的代码的区域文化中的千分位分隔符而没有指定 NumberStyles.AllowThousands 或者您指定了 NumberStyles.AllowThousands 但在区域文化中放入了错误的 千分位分隔符,以及/或
    • c) 小数点分隔符(在 int 解析中不应该存在)

不正确的示例:

情况1

a = Int32.Parse("5000000000"); //5 billions, too large
b = Int32.Parse("-5000000000"); //-5 billions, too small
//The limit for int (32-bit integer) is only from -2,147,483,648 to 2,147,483,647

情况2 a)

a = Int32.Parse("a189"); //having a 
a = Int32.Parse("1-89"); //having - but not in the beginning
a = Int32.Parse("18 9"); //having space, but not in the beginning or end

情况2 b)

NumberStyles styles = NumberStyles.AllowThousands;
a = Int32.Parse("1,189"); //not OK, no NumberStyles.AllowThousands
b = Int32.Parse("1,189", styles, new CultureInfo("fr-FR")); //not OK, having NumberStyles.AllowThousands but the culture specified use different thousand separator

情况2 c)

NumberStyles styles = NumberStyles.AllowDecimalPoint;
a = Int32.Parse("1.189", styles); //wrong, int parse cannot parse decimal point at all!

表面上不对,但实际上是正确的例子:

情况2 a) 正确

a = Int32.Parse("-189"); //having - but in the beginning
b = Int32.Parse(" 189 "); //having space, but in the beginning or end

案例2b)通过

NumberStyles styles = NumberStyles.AllowThousands;
a = Int32.Parse("1,189", styles); //ok, having NumberStyles.AllowThousands in the correct culture
b = Int32.Parse("1 189", styles, new CultureInfo("fr-FR")); //ok, having NumberStyles.AllowThousands and correct thousand separator is used for "fr-FR" culture

解决方案

在所有情况下,请使用您的Visual Studio调试器检查textBox1.Text的值,并确保它具有适合于int范围的纯粹可接受的数字格式。类似于这样:

1234

此外,您可以考虑使用TryParse而不是Parse来确保未解析的数字不会导致异常问题。

  1. 检查TryParse的结果,如果不为true,则处理它。

int val;
bool result = int.TryParse(textbox1.Text, out val);
if (!result)
    return; //something has gone wrong
//OK, continue using val

4

在我的情况下,我忘记了使用双花括号来进行转义。{{myobject}}


什么?那怎么能是问题的答案呢?我们甚至不知道“你的情况”是什么… - nvoigt
1
@zawhtut 当你回答 OP 的问题时,该问题已经存在7年了。您需要澄清您的情况是什么,以及如何通过使用双花括号解决了您遇到的问题。您还应该包括有关您正在使用的语言的详细信息。OP的问题涉及C#。您提到的双花括号“{{}}”超出了上下文,但强烈暗示您正在使用不同的语言或模板库,这对OP的情况没有任何影响或好处。 - OldBuildingAndLoan

4
您在使用带有无效括号语法的字符串格式化程序时可能会遇到此异常。
// incorrect
string.Format("str {incorrect}", "replacement")

// correct
string.Format("str {1}", "replacement")

我在我的第一个参数“{0:c2}”前面有一个空格,这导致了问题。 - Enkode

3

您没有提到文本框在设计时是否有值或现在是否有值。当表单初始化时,如果您在表单设计期间没有将值放入文本框中,则文本框可能没有值。您可以通过在设计时设置文本属性来为表单设计添加int值,并且这应该可以正常工作。


0
我曾经遇到过类似的问题,我用以下技巧解决了它:
异常是在以下代码行抛出的(请参见下面用**标记的文本):
static void Main(string[] args)
    {

        double number = 0;
        string numberStr = string.Format("{0:C2}", 100);

        **number = Double.Parse(numberStr);**

        Console.WriteLine("The number is {0}", number);
    }

经过一番调查,我意识到问题在于格式化字符串中包含了一个美元符号($),而Parse/TryParse方法无法解析(即去除)。因此,我使用了字符串对象的Remove(...)方法将该行代码更改为:
number = Double.Parse(numberStr.Remove(0, 1)); // Remove the "$" from the number

这时候,Parse(...) 方法按预期工作。


0

这也是我的问题... 在我的情况下,我将波斯数字更改为拉丁数字,然后它就可以工作了。 并且在转换之前也要修剪您的字符串。

PersianCalendar pc = new PersianCalendar();
char[] seperator ={'/'};
string[] date = txtSaleDate.Text.Split(seperator);
int a = Convert.ToInt32(Persia.Number.ConvertToLatin(date[0]).Trim());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接