Ciąg wejściowy nie był w poprawnym formacie


83

Jestem nowy w C #, mam podstawową wiedzę w Javie, ale nie mogę sprawić, by ten kod działał poprawnie.

To tylko podstawowy kalkulator, ale kiedy uruchamiam program VS2008 daje mi taki błąd:

Kalkulator

Zrobiłem prawie ten sam program, ale w javie używając JSwing i działał idealnie.

Oto forma języka C #:

Formularz

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

Jaki może być problem? Czy jest sposób na rozwiązanie tego problemu?

PS: Ja też próbowałem

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

i to nie zadziałało.

Odpowiedzi:


111

Błąd oznacza, że ​​ciąg, z którego próbujesz przeanalizować liczbę całkowitą, w rzeczywistości nie zawiera prawidłowej liczby całkowitej.

Jest bardzo mało prawdopodobne, aby pola tekstowe zawierały prawidłową liczbę całkowitą natychmiast po utworzeniu formularza - czyli tam, gdzie otrzymujesz wartości całkowite. Znacznie bardziej sensowne byłoby zaktualizowanie ai bkliknięcie przycisku (w ten sam sposób, w jaki jesteś w konstruktorze). Sprawdź również Int.TryParsemetodę - jest znacznie łatwiejsza w użyciu, jeśli ciąg może w rzeczywistości nie zawierać liczby całkowitej - nie zgłasza wyjątku, więc łatwiej jest go odzyskać.


2
Ten komunikat o błędzie może zostać zgłoszony również podczas próby Convert.ToDouble danych wejściowych pochodzących od użytkownika z różnymi informacjami o kulturze, więc można użyć Convert.ToDouble (String, IFormatProvider) zamiast po prostu Convert.ToDouble (String). Trudno go debugować, ponieważ program będzie działał w twoim systemie, ale będzie generował błąd na niektórych jego użytkowników, dlatego mam metodę logowania błędów na moim serwerze i szybko znalazłem problem.
vinsa

58

Natrafiłem na ten dokładny wyjątek, z wyjątkiem tego, że nie miał on nic wspólnego z analizowaniem danych liczbowych. Więc to nie jest odpowiedź na pytanie OP, ale myślę, że dzielenie się wiedzą jest dopuszczalne.

Zadeklarowałem ciąg znaków i formatowałem go do użytku z JQTree, które wymaga nawiasów klamrowych ({}). Musisz użyć podwójnych nawiasów klamrowych, aby został zaakceptowany jako poprawnie sformatowany ciąg:

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"]);

Mamy nadzieję, że pomoże to innym osobom, które znajdą to pytanie, ale nie analizują danych liczbowych.


19

Jeśli nie sprawdzasz jawnie liczb w polu tekstowym, w każdym razie lepiej jest użyć

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

Teraz, jeśli wynik jest sukcesem, możesz kontynuować obliczenia.


11
Zazwyczaj resultnie trzeba go inicjować.
yazanpro

12

Problemy

Istnieje kilka możliwych przypadków wystąpienia błędu:

  1. Ponieważ textBox1.Textzawiera tylko liczbę, ale liczba jest za duża / za mała

  2. Ponieważ textBox1.Textzawiera:

    • a) nieliczbowe (z wyjątkiem spacepoczątku / końca,- początku) i / lub
    • b) separatory tysięcy w zastosowanej kulturze dla twojego kodu bez określania NumberStyles.AllowThousandslub określania, NumberStyles.AllowThousandsale źle wstawianethousand separator w kulturze i / lub
    • c) separator dziesiętny (który nie powinien istnieć podczas intanalizowania)

NIE OK Przykłady:

Przypadek 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

Przypadek 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

Przypadek 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

Przypadek 2 c)

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

Pozornie NIE OK, ale w rzeczywistości OK Przykłady:

Przypadek 2 a) OK

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

Przypadek 2 b) OK

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

Rozwiązania

We wszystkich przypadkach sprawdź wartość w textBox1.Textdebugerze programu Visual Studio i upewnij się, że ma on całkowicie akceptowalny format liczbowy dla intzakresu. Coś takiego:

1234

Możesz również rozważyć

  1. using TryParsezamiast of, Parseaby upewnić się, że niepanowany numer nie spowoduje problemu z wyjątkiem.
  2. sprawdź wynik TryParsei zajmij się nim, jeśli nietrue

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

3

Nie wspomniałeś, czy twoje pole tekstowe ma wartości w czasie projektowania, czy teraz. Kiedy formularz jest inicjowany, pole tekstowe może nie mieć wartości, jeśli nie umieściłeś go w polu tekstowym podczas projektowania formularza. możesz umieścić wartość int w projekcie formularza, ustawiając właściwość text w desgin i to powinno działać.


3

W moim przypadku zapomniałem założyć podwójną klamrę, aby uciec. {{myobject}}


0

to też był mój problem ... w moim przypadku zmieniłem numer PERSKI na numer LATIN i zadziałało. ORAZ również przetnij swój ciąg przed konwersją.

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

0

Miałem podobny problem, który rozwiązałem następującą techniką:

Wyjątek został zgłoszony w następującym wierszu kodu (zobacz tekst ozdobiony ** poniżej):

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

Po krótkiej analizie zdałem sobie sprawę, że problem polegał na tym, że sformatowany ciąg zawierał znak dolara ($), którego metody Parse / TryParse nie mogą rozwiązać (tj. - strip off). Więc używając metody Remove (...) obiektu string, zmieniłem linię na:

number = Double.Parse(numberStr.Remove(0, 1)); // Remove the "$" from the number

W tym momencie metoda Parse (...) działała zgodnie z oczekiwaniami.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.