2015-03-17 3 views
1

Итак, я сделал калькулятор на C#, но он не может вычислить десятичные числа. Он работает отлично, когда нажимает, например, кнопки: 6. (это точка) затем 5. Но как только я нажимаю на кнопку «+» (или любой другой оператор) после этого в форме, программа останавливается, и я получаю сообщение о том, чтоНевозможно вычислить десятичные числа в моем калькуляторе

" Необработанное исключение типа «System.FormatException» произошло в mscorlib.dll. Входная строка не была в правильном формате ».

Я не знаю, как это решить. Есть ли кто-нибудь, кто знает, как решить эту проблему?

Вот мой код:

namespace Kalkylator{ 
    public partial class Form1 : Form{ 
     String operation = ""; //the operation we will use 
     Double resultat = 0; //the result we will get 
     bool finished = false; //if false, we have not pressed the "=" button yet 

     public Form1(){ 
      InitializeComponent(); 
     } 

     // 
     private void button_click(object sender, EventArgs e){ 
      if (finished == true){ //if we press any operator, clear the textbox-window so new numbers can be entered 
       textBoxFonster.Clear(); 
      } 
      finished = false; //we are not done with the calculation 
      Button b = (Button)sender; 

      if (b.Text == "."){ 
       if (!textBoxFonster.Text.Contains(".")){ 
        textBoxFonster.Text = textBoxFonster.Text + b.Text; 
       } 
      } 
      else{ 
       textBoxFonster.Text = textBoxFonster.Text + b.Text; //writes the number in the textBox 
      } 
     } 

     private void operator_click(object sender, EventArgs e) 
     { 
      Button b = (Button)sender; 
      operation = b.Text; //the operation we will perform is the operatorButton we will press 
      resultat = Double.Parse(textBoxFonster.Text); //HERE IS WHERE THE PROGRAM GIVES ME THE ERROR. 
      finished = true; //we are done with the calculation 
     } 

     private void clear_click(object sender, EventArgs e) 
     { 
      textBoxFonster.Text = ""; //clear the window from all text 
      resultat = 0; //clear the value of resultat and set it to 0 
     } 

     private void LikaMed_click(object sender, EventArgs e) 
     { 
      switch(operation){ 
       case "+": //add the result with the text in the textBox 
        textBoxFonster.Text = (resultat + Double.Parse(textBoxFonster.Text)).ToString(); 
        break; 
       case "-": 
        textBoxFonster.Text = (resultat - Double.Parse(textBoxFonster.Text)).ToString(); 
        break; 
       case "*": 
        textBoxFonster.Text = (resultat * Double.Parse(textBoxFonster.Text)).ToString(); 
        break; 
       case "%": 
        textBoxFonster.Text = (resultat/Double.Parse(textBoxFonster.Text) * (resultat/100)).ToString(); 
        break; 
       case "^": 
        textBoxFonster.Text = (Math.Pow(resultat, Double.Parse(textBoxFonster.Text))).ToString(); 
        break; 
       case "Log": //takes the 10th log of resultat 
        textBoxFonster.Text = (Math.Log10(resultat)).ToString(); 
        break; 
       case "Sqrt": 
        textBoxFonster.Text = (Math.Sqrt(resultat)).ToString(); 
        break; 
       case "/": //divide the result with the text in the textBox if that text is not 0. If so, show an error message 
        if ((Double.Parse(textBoxFonster.Text)) != 0){ 
         textBoxFonster.Text = (resultat/Double.Parse(textBoxFonster.Text)).ToString(); 
        } 
        else{ //show error in MessageBox 
         MessageBox.Show("Cannot divide by 0!"); 
        } 
        break; 
       default: 
        break; 
      } 
      finished = true; //this will clear the result textbox when clicking another number after the equal sign has been clicked 
     } 
    } 
} 
+2

Угадайте, находитесь ли вы в локали, которая обычно использует ',' для указания десятичной точки? – Phylogenesis

+0

На какой строке точно? Можете ли вы показать пример настроек ввода и культуры? –

+1

@Phylogenesis Спасибо! Вы абсолютно правы. Даже не подумал об этом, и теперь он работает :) – chue

ответ

1

Не используйте Double.Parse без указания культуры.

Изменение:

switch(operation){ 
    case "+": //add the result with the text in the textBox 
     textBoxFonster.Text = (resultat + Double.Parse(textBoxFonster.Text)).ToString(); 
     break; 
    case "-": 
     textBoxFonster.Text = (resultat - Double.Parse(textBoxFonster.Text)).ToString(); 
     break; 

к:

Double operand1=resultat; 
Double operand2=0; 
Double.TryParse(textBoxFonster.Text,NumberStyles.Float,CultureInfo.InvariantCulture,out operand2); 
switch(operation){ 
    case "+": //add the result with the text in the textBox 
     textBoxFonster.Text = (operand1 + operand2).ToString(); 
     break; 
    case "-": 
     textBoxFonster.Text = (operand1 - operand2).ToString(); 
     break; 

В качестве альтернативы, вы могли бы на самом деле поддержки нескольких культур, и изменить этот код:

 if (b.Text == "."){ 
      if (!textBoxFonster.Text.Contains(".")){ 
       textBoxFonster.Text = textBoxFonster.Text + b.Text; 
      } 
     } 

к этому:

 if (b.Text == System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator){ 
      if (!textBoxFonster.Text.Contains(System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator)){ 
       textBoxFonster.Text = textBoxFonster.Text + b.Text; 
      } 
     } 
+0

Могу ли я спросить вас, почему важно указать Культуру? Это мой первый раз услышать об этом. – chue

+1

Потому что без него вы будете использовать культуру по умолчанию системы. Так как ваш код ожидает. как разделитель десятичных чисел в некоторых местах, вы должны указать, что при попытке разобрать текст на цифры. Не все культуры используют. чтобы указать разделитель десятичных чисел, и если вы запустите свой код на машине с культурой по умолчанию, которая разделит десятичный разделитель как и разделитель тысяч как., затем дважды. Параметр будет анализировать (1.002 как 1002 и проанализировать 1,002 как 1.002 и т. д.), –

Смежные вопросы