LoginSignup
6
7

More than 5 years have passed since last update.

C#+Windows Formで作るダメな電卓例(改善版)

Posted at

概要

前回の内容の改善版です。

内容

calc.cs

using System;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace calc
{
    public partial class Form1 : Form
    {
        private bool Form_Write_Permit = true;

        public Form1()
        {
            InitializeComponent();
        }

        private void btnNumber_Click(object sender, EventArgs e)
        {
            if (Form_Write_Permit == false)
            {
                return;
            }
            textBoxCalc.Text += ((Button)sender).Text;
        }

        private void Op_Click(object sender, EventArgs e)
        {
            if (input_check() != 1)
            {
                return;
            }
            textBoxCalc.Text += ((Button)sender).Text;
        }

        private void point_Click(object sender, EventArgs e)
        {
            if(input_check() != 1)
            {
                return;
            }
            textBoxCalc.Text += '.';
        }

        private void Clear_Click(object sender, EventArgs e)//式の初期化
        {
            textBoxCalc.Text = String.Empty;
            Form_Write_Permit = true;
        }

        private void eq_Click(object sender, EventArgs e)//式の計算を行う
        {
            char Operator = ' ';
            string Form_Num_Copy = string.Empty;
            double Form_Check;
            double Left_Value = 0.0; //演算子で式を分けた時の左と右の数値
            double Right_Value = 0.0;
            bool First_Found = true; // 初回の計算かどうか判定

            //  フォーム内に数値以外もしくは空のときに"="を押しても何もしない
            if (double.TryParse(textBoxCalc.Text, out Form_Check) || textBoxCalc.Text == "")
            {
                    return;
            }

            for (int i = 0; i < textBoxCalc.Text.Length;i++) //フォームから1文字ずつ読みだす
            {
                char Char_Temp = textBoxCalc.Text[i];
                if (Char.IsDigit(Char_Temp) == true || Char_Temp == '.') //数値もしくは小数点の場合
                {
                    Form_Num_Copy += Char_Temp;    //数値のコピーをとっておく
                    if(i == textBoxCalc.Text.Length - 1)//数値挿入時点で式が終了するか調べる
                    {
                        Right_Value = double.Parse(Form_Num_Copy);
                        Left_Value = calc(Left_Value, Right_Value, Operator);
                        Form_Num_Copy = string.Empty;
                    }
                }
                else if (Char_Temp == '+' || Char_Temp == '-' || Char_Temp == '*' || Char_Temp == '/')//いずれかの演算子の場合
                {
                    if(First_Found == true)//初めて演算子を見つけたとき
                    {
                        Left_Value = double.Parse(Form_Num_Copy);//1回目のLeft_Valueの代入
                        Form_Num_Copy = string.Empty;
                        First_Found = false;
                    }
                    else  //  2回目以降の演算
                    {
                        Right_Value =  double.Parse(Form_Num_Copy);
                        Left_Value = calc(Left_Value, Right_Value, Operator);
                        Form_Num_Copy = string.Empty;
                    }
                    Operator = Char_Temp;
                }               
            }
            textBoxCalc.Text = Left_Value.ToString();
            Form_Write_Permit = false;//計算後に数値を入力しても受け付けないようにする
        }

        private double calc(double x, double y,char op)
        {
            double ans = 0.0;
            switch(op)
            {
                case '+':
                    ans =  x + y;
                    break;
                case '-':
                    ans = x - y;
                    break;
                case '*':
                    ans = x * y;
                    break;
                case '/':
                    ans = x / y;
                    break;
            }
            return ans;
        }

        // 入力内容のチェック
        private int input_check()
        {
            if (textBoxCalc.Text == string.Empty)
            {
                return -1;
            }
            else if (textBoxCalc.Text[textBoxCalc.Text.Length - 1] == '+' || textBoxCalc.Text[textBoxCalc.Text.Length - 1] == '-' ||
                textBoxCalc.Text[textBoxCalc.Text.Length - 1] == '*' || textBoxCalc.Text[textBoxCalc.Text.Length - 1] == '/' ||
                textBoxCalc.Text[textBoxCalc.Text.Length - 1] == '.')
            {
                return -1;
            }
            return 1;
        }
    }
}

改善点

前回より無駄な変数、ロジックが減り、特にeq_Click内がスッキリしました!
・フォーム内の位置から数値、演算子を取り出す方式は廃止
・入力チェックの追加

フォーム中の左から逐次的に読むのは前と変わらずですが
・読み込み中に始めて数値を見つけた時→Left_Value(左辺兼計算結果の変数)に格納
・2回目以降の数値を見つけた時→右辺に数値をいれて、その時の演算子とLeft_Valueで計算

というようにしています。

残りの改善点は
・C#であるに関わらず、オブジェクト指向的な書き方ではない。C的な書き方をしている。
・フォーム内の直接書き換えを考慮していない(ボタン入力式と割り切ればOK?)

だと思います。
オブジェクト指向的に書けるようになるのは課題ですね。

まとめ

まだ改善点はありますが、前回よりは幾分ましなコードになりました(;_;)
今後ともコードの精査は行っていきたいと思います。

6
7
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7