日常以外(もしくは日常)

勉強したこととか考えたことを書きます。なるほどを求めているので。

C# で 電卓作ってみた

C#で電卓を作りました。

  

経緯

未経験でIT系の会社に入社してみたはいいものの、何もかもさっぱり分からない日々を送っています。  
C#を職場の研修でちょっと勉強したので、せっかくなので休日にも触ってみることにしました。  
また、プラグラミングを学ぶ過程でとりあえず電卓を作れるようになると良いということをどこかで読みました。  
そこで粗悪ながらもとりあえず見よう見まねで作ってみましたので、コードと工夫点を載せておきます。  

コード

※言い訳がましいですが、まだ言葉の意味を理解しないでコメントを書いている部分も多いです。間違いがあればご指摘いただけると嬉しいです。

using System;

namespace Calculator
{
    class MainClass
    {        
        //入力された文字はなんでもここに入れる
        static string i = null;

        //iが数字だったらこれに入れる
        static string input = null;

        //計算結果を入れる。
        //double型だと割り算の時に誤差が出るのでdecimal型
        static decimal result = 0;

        //iが四則演算子と=だったらこれに入れる
        static string ope = null;

        public static void Main(string[] args)
        {
            //前書き
            Console.WriteLine("電卓です。以下のどれかを項目ごとに順に入力してください。\r\n" +
                              "数字、四則演算子、数字、......=の順に入力すると計算できます。\r\n" +
                              "四則演算子:+ - * / \r\n" +
                              "数字:いわゆる数字です。数字を連続で入力すると上書きできます\r\n" +
                              "=:押すと計算結果が出ます。また、それまでの入力は初期化されます。\r\n" +
                              "AC:初期化されます。\r\n" +
                              "END:終了します。");

            //延々ループさせ入力待ち状態にする
            //whileの条件、他にいいのないのかな?今回はこれで。
            while(i!="END"){
                Console.WriteLine("入力してください");
                i = Console.ReadLine();
                decimal d;

                if(decimal.TryParse(i, out d)){
                    //iがdecimalに変換できるか(つまり数字かどうか)を判定
                    //数字だったらinputに入れる
                    input = i;
                }else if (ope == null && i == "="){
                    //いきなり押すとエラーがでる?ので無理やり回避。
                    //詳細がわかったらもうちょっと見栄え良く直せそう
                    Console.WriteLine("いきなり=を押さないでね");
                }else if(i=="+"||i == "-"||i == "*"||i == "/"||i == "="){
                    //iが四則演算子または=だったらKeisannメソッドを呼ぶ。
                    Keisann();
                }else if(i=="AC"){
                    //iがACだったらAll_Clearメソッドを呼ぶ。
                    All_Clear();
                }else if(i=="END"){
                    //iがENDだったら何もしないでもう一周する
                }else{
                    //上記のどれでもなかったら以下を表示
                    Console.WriteLine("入力が間違っているみたいです");
                }
            }
            //コンソールを終了させる
            Environment.Exit(0);  
        }

        public static void Keisann()
        {//計算するところ
            decimal num1 = result;
            decimal num2 = decimal.Parse(input);

            //opeで判定。前回の演算子か=を判定するよ
            switch (ope)
            {
                case "+":
                    //足し算
                    result = num1 + num2;  
                    break;

                case "-":
                    //引き算
                    result = num1 - num2;
                    break;

                case "*":
                    //掛け算
                    result = num1 * num2;
                    break;

                case "/":
                    //割り算
                    if(num2!=0)
                    {//0で割ることはできないので避けます
                        result = num1 / num2;
                        
                    }else{
                        //もし0で割り算しようとしたらメッセージを出した上で初期状態にします。
                        Console.WriteLine("0で割ることができません\r\n初期状態にしました");
                        All_Clear();
                    }
                    break;

                 case null:
                    //1回目の演算子入力ではただinputをresultに入れるだけです
                    result = decimal.Parse(input);
                    break;

                default:
                    //念のため
                    break;
            }

            ope = i;
            //演算子をopeに入れる

            if(ope=="=")
            {//もしopeが=だったら(今回=が押されていたら)計算結果を表示
                //型変換することで不要な0を消す
                string str = result.ToString();
                double d = double.Parse(str);

                Console.WriteLine(d+"\r\n計算がおわったよ");
                All_Clear();
            }
        }
        public static void All_Clear()
        {//全部初期化って時に呼びます。
            input = null;
            result = 0;
            ope = null;
            i = null;
        }
    }
}

  
  

工夫点

引き算の時にできてしまう不要な0を消す

  
1.0001-0.0001= と計算した時に、  
答えは「1」となるのが自然に感じられますが、  
decimal型を使うと「1.0000」となってしまいます。
  
f:id:nyappokun:20180610010022p:plain:w180
  △こうなっちゃう
  
私はそれが嫌だったので、無理やり
decimal型→string型→double型と変換し、不要な0を消してみました。
  
f:id:nyappokun:20180610014154p:plain:w400
  △無理やり型変換
  
f:id:nyappokun:20180610014312p:plain:w180
  △電卓的に自然な数字になる

素人考えかもですが、きれいに収まった感じがして満足しました。

終わりに

電卓って本当はもっと機能あるなーと思いつつ、できる範囲で最小限で作りました。  
±変換とか、掛け算割り算の優先機能とかがないので、結構単純に作れたかと思います。  
もしスキルが上がってダメダメジャーンとなったら直すかと思いますが、  
とりあえずプログラミング経験2ヶ月の人間が作った電卓ってこんな感じです、という一例です。  
  
  
2度目ですが、間違いやもっといい書き方があればご指摘いただけると嬉しいです。  
以上、C# で 電卓作ってみた、でした。