C#で電卓は新人研修には厳しいってばよ。

 新人研修にて,C#で電卓を0から作らされたので、必死にあがいた痕跡を残しておきます。VisualStudio2019を使用。

機能
・小数点・マイナス計算可能
・演算子打ち直し可能
・＝押さなくても計算結果表
・最大桁数は16桁で超過の場合エラーメッセージ表示、表示後Cボタン以外使用不可になる


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572051/4c256bbe-eff2-a67d-d1cb-078144de932d.png)

難航した点
・小数点とカンマの共存
→カンマ区切り表示はdecimalだけど、小数点はstring

#数値入力

```csharp
using System;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace WinFormsApp1
{

    public partial class Form1 : Form
    {      

        string input_str = "";//入力値       
        string Enzansi = null;//演算子
        decimal num1 = 0;//計算する数値
        decimal num2 = 0;
        decimal result = 0;
        bool enzansi = false;


      private void Numberbutton_Click(object sender, EventArgs e)
        {
            enzansi = false;
            Button nbtn = (Button)sender;
            string text = nbtn.Text;

            if (Enzansi == "=")
            {
                keisanlabel.Text = "";
                resultlabel.Text = "";
                Enzansi = null;
                num1 = 0;
                result = 0;
            }
            //桁数上限16桁
            Regex re = new Regex(@"[^0-9]");
            string digit = re.Replace(input_str, "");
            if (digit.Length <= 15)
            {
                bool dot = resultlabel.Text.Contains(".");
                if (dot)//小数点あり数値表示
                {
                    input_str += text;
                    resultlabel.Text = string.Format("{0:#,0.###############}"
                        , decimal.Parse(input_str));

                    if (input_str.Contains(".0"))
                    {
                        resultlabel.Text = string.Format("{0:#,0.###############}"
                            , decimal.Parse(input_str)) + "." + "0";
                    }
                }
                else if (text == "0")//最初に0押したとき
                {
                    input_str += text;
                    resultlabel.Text = String.Format("{0:#,0}", decimal.Parse(input_str));
                    return;
                }
                else//0以外の数字押したとき
                {
                    input_str += text;
                    input_str = input_str.TrimStart('0');
                    resultlabel.Text = String.Format("{0:#,0}", decimal.Parse(input_str));
                }

            }
            else
            {
                MessageBox.Show("表示可能な桁数を超えました", "桁数超過エラー",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                buttonEnabled(false);
            }
        }
```
#計算メソッド
   ```csharp
       
        private void Enzansibutton_Click(object sender, EventArgs e)
        {
            num1 = result;
            if (input_str != "")
            {
                num2 = decimal.Parse(input_str);
                if (Enzansi == "+") { result = num1 + num2; }
                if (Enzansi == "-") { result = num1 - num2; }
                if (Enzansi == "×") { result = num1 * num2; }
                if (Enzansi == "÷") { result = num1 / num2; }
                if (Enzansi == null) { result = num2; }
            }
            Button obtn = (Button)sender;//演算子格納
            Enzansi = obtn.Text;

            keisanlabel.Text = keisanlabel.Text + input_str;
            input_str = "";

            if (enzansi)//演算子ボタンが連続で押されたとき置換
            {
                string keisan = keisanlabel.Text = keisanlabel.Text.Remove(keisanlabel.Text.Length - 1);
                keisanlabel.Text = keisan + Enzansi;

            }
            else//一回目
            {
                keisanlabel.Text += Enzansi;
                enzansi = true;

            }
            //=押さなくても計算結果表示
            resultlabel.Text = String.Format("{0:#,0.###############}", result);

            bool keisandot = keisanlabel.Text.Contains(".");
            bool resultdot = Convert.ToString(result).Contains(".");
            if (keisandot)//計算式に小数点がある
            {
                resultlabel.Text = String.Format("{0:#,0.###############}", result);
            }
            else if (resultdot)//計算式にないが、結果にある
            {
                resultlabel.Text = String.Format("{0:#,0.###############}", result);
            }

            if (Enzansi == "=")
            {
                resultlabel.Text = String.Format("{0:#,0.###############}", result);

                if (keisandot)//計算式に小数点がある
                {
                    resultlabel.Text = String.Format("{0:#,0.###############}", result);
                }
                else if (resultdot)//計算式にないが、結果にある
                {
                    resultlabel.Text = String.Format("{0:#,0.###############}", result);
                }
                if (result.ToString().Length > 16)
                {
                    MessageBox.Show("表示可能な桁数を超えました", "桁数超過エラー",
                                            MessageBoxButtons.OK, MessageBoxIcon.Error);
                    buttonEnabled(false);
                }
                input_str = "";
            }
        }
   ```
#小数点・プラマイボタン
   ```csharp
        private void dot_Click(object sender, EventArgs e)
        {
            bool dot = resultlabel.Text.Contains(".");
            if (dot) { return; }//小数点重複回避
            else
            {
                input_str += buttonDot.Text;
                resultlabel.Text = String.Format("{0:#,0.###############}", decimal.Parse(input_str)) + ".";
            }
        }
        
        private void pm_Click(object sender, EventArgs e)
        {
            decimal num = Convert.ToDecimal(resultlabel.Text);
            if (num > 0)
            {
                input_str += "-" + num;
                resultlabel.Text = String.Format("{0:#,0.###############}", decimal.Parse(input_str));
            }
            else
            {
                input_str = input_str.Remove(0, 1);
                resultlabel.Text = String.Format("{0:#,0.###############}", decimal.Parse(input_str));
            }
        }
   ```
#クリアボタン
   ```csharp
        private void CE_Click(object sender, EventArgs e)
        {
            if (Enzansi == "=")
            {
                keisanlabel.Text = "";
                resultlabel.Text = "0";
                input_str = "";
            }
            else
            {
                resultlabel.Text = "0";
                input_str = "";
            }

        }
        
        private void C_Click(object sender, EventArgs e)
        {
            keisanlabel.Text = "";
            resultlabel.Text = "0";
            input_str = "";
            Enzansi = null;
            num1 = 0;
            num2 = 0;
            result = 0;
            buttonEnabled(true);
        }

    //エラーのあとボタン使用不可
        private void buttonEnabled(bool con)
        {
            button1.Enabled = con;
            button2.Enabled = con;
            button3.Enabled = con;
            button4.Enabled = con;
            button5.Enabled = con;
            button6.Enabled = con;
            button7.Enabled = con;
            button8.Enabled = con;
            button9.Enabled = con;
            button0.Enabled = con;
            buttonCE.Enabled = con;
            buttonDot.Enabled = con;
            buttonPM.Enabled = con;
            buttonEqual.Enabled = con;
            buttonKakeru.Enabled = con;
            buttonMinus.Enabled = con;
            buttonPlus.Enabled = con;
            buttonWaru.Enabled = con;
        }
    }
}
   ```