Вхідна рядок не була в правильному форматі


83

Я новачок у C #, я маю деякі базові знання в Java, але я не можу змусити цей код працювати належним чином.

Це просто основний калькулятор, але коли я запускаю програму VS2008 видає мені цю помилку:

Калькулятор

Я зробив майже ту саму програму, але в Java, використовуючи JSwing, і вона працювала чудово.

Ось форма c #:

Форма

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

і це не спрацювало.

Відповіді:


111

Помилка означає, що рядок, з якого ви намагаєтесь проаналізувати ціле число, насправді не містить дійсного цілого числа.

Надзвичайно малоймовірно, що текстові поля будуть містити дійсне ціле число відразу при створенні форми - саме там ви отримуєте цілі значення. Набагато більше сенсу було б оновлювати aта bнатискати кнопки подій (так само, як і в конструкторі). Також перевірте Int.TryParseметод - набагато простіший у використанні, якщо рядок може насправді не містити цілого числа - він не видає винятку, тому його легше відновити.


2
Це повідомлення про помилку може бути видане також при спробі Convert.ToDouble введення, що надходить від користувача з іншою інформацією про культуру, тому ви можете використовувати Convert.ToDouble (String, IFormatProvider) замість просто Convert.ToDouble (String). Важко налагодити, оскільки програма буде працювати у вашій системі, але буде видавати помилку деяким її користувачам, ось чому у мене є метод реєструвати помилки на моєму сервері, і я швидко дізнався про проблему.
вінса

58

Я зіткнувся з цим точним винятком, за винятком того, що це не мало нічого спільного з синтаксичним розбором числових входів. Отже, це не відповідь на запитання ОП, але я вважаю прийнятним ділитися знаннями.

Я оголосив рядок і відформатував його для використання з 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"]);

Сподіваємось, це допоможе іншим, хто знайшов це питання, але не аналізує числові дані.


18

Якщо ви не перевіряєте явно цифри в текстовому полі, у будь-якому випадку його краще використовувати

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

Тепер, якщо результат досяг успіху, ви можете продовжувати свої розрахунки.


11
Зазвичай resultне потрібно ініціалізувати.
yazanpro

12

Проблеми

Є кілька можливих випадків, чому виникає помилка:

  1. Оскільки textBox1.Textмістить лише число, але число занадто велике / замале

  2. Оскільки textBox1.Textмістить:

    • а) нечислові (крім spaceпочатку / кінця, -на початку) та / або
    • б) тисячі розділювачів у застосованій культурі для вашого коду, не вказуючи NumberStyles.AllowThousandsабо ви вказали, NumberStyles.AllowThousandsале неправильно ввели thousand separatorкультуру та / або
    • в) десятковий роздільник (який не повинен існувати при intрозборі)

NOT OK Приклади:

Випадок 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 = 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 б)

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 в)

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

Начебто НЕ ОК, але насправді ОК Приклади:

Випадок 2 а) Добре

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

Випадок 2 б) Добре

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

Рішення

У всіх випадках перевірте значення за textBox1.Textдопомогою налагоджувача Visual Studio та переконайтеся, що він має чисто прийнятний числовий формат для intдіапазону. Щось на зразок цього:

1234

Крім того, ви можете розглянути

  1. використання TryParseзамість того, Parseщоб переконатися, що непроаналізований номер не викликає у вас проблем з винятками.
  2. перевірити результат TryParseі впоратися з ним, якщо ніtrue

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

3

Ви не згадували, чи є у вашому текстовому полі значення під час проектування чи зараз. Коли форма ініціалізує текстове поле, може не мати значення, якщо ви не помістили його в текстове поле під час проектування форми. Ви можете ввести значення int у дизайн форми, встановивши властивість text у desgin, і це має спрацювати.


3

У моєму випадку я забув поставити подвійну фігурну дужку, щоб врятуватися. {{myobject}}


0

це була моя проблема теж .. у моєму випадку я змінив ПЕРСІЙНИЙ номер на ЛАТИНСЬКИЙ номер, і це спрацювало. А також обрізати рядок перед перетворенням.

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

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 (...) працював належним чином.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.