質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

3回答

3509閲覧

**1+2+3のような、連続で計算がしたい。**

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

1クリップ

投稿2019/04/12 15:26

編集2019/04/15 12:18

C#を始めて1週間足らずで、理解が追いついていないところも多々あるので、
お力をお貸しください。。。

現在、C#にて電卓の作成をしております。
ですが、どうにも
1+2+3のような、連続した計算のやり方がわかりません。
iPhoneの計算機のような計算がしたいです。

該当のソースコード

C#

1namespace WindowsFormsApp1 2{ 3 public partial class Form1 : Form 4 { 5 public Form1() 6 { 7 InitializeComponent(); 8 } 9 10 bool isFirst = true; 11 decimal num1 = 0; 12 13 //数字のボタンを押したとき 14 private void Number_Click(object sender, EventArgs e) 15 { 16 if (sign != arithmetic.undefined && isFirst) 17 { 18 num1 = Convert.ToDecimal(textDisplay.Text); 19 textDisplay.Text = ""; 20 isFirst = false; 21 } 22 23 if (textDisplay.TextLength == 10) 24 { 25 return; 26 } 27 28 textDisplay.Text = 29 textDisplay.Text + ((Button)sender).Text; 30 31 } 32 33 //小数点を押したとき 34 private void Dot_Click(object sender, EventArgs e) 35 { 36 if (textDisplay.Text.IndexOf(".") >= 0) 37 { 38 return; 39 } 40 textDisplay.Text = textDisplay.Text + "."; 41 } 42 43 //四則演算 44 enum arithmetic 45 { 46 undefined,ADD,SUB,MUL,DIV 47 }; 48    arithmetic sign = arithmetic.undefined; 49 50 //足し算 51 ★private void ADD_Click(object sender, EventArgs e) 52 { 53 sign = arithmetic.ADD; 54 isFirst = true; 55 } 56 57 //引き算 58 ★private void SUB_Click(object sender, EventArgs e) 59 { 60 sign = arithmetic.SUB; 61 isFirst = true; 62 } 63 64 //掛け算 65 ★private void MUL_Click(object sender, EventArgs e) 66 { 67 sign = arithmetic.MUL; 68 isFirst = true; 69 70 } 71 72 //割り算 73 ★private void DIV_Click(object sender, EventArgs e) 74 { 75 sign = arithmetic.DIV; 76 isFirst = true; 77 78 } 79 80 //イコールを押したとき 81 private void Equal_Click(object sender, EventArgs e) 82 { 83 decimal num2 = decimal.Parse(textDisplay.Text); 84 decimal Result = 0; 85 86 //switch構文 87 switch (sign) { 88 case arithmetic.ADD: 89 Result = num1 + num2; 90 break; 91 case arithmetic.SUB: 92 Result = num1 - num2; 93 break; 94 case arithmetic.MUL: 95 Result = num1 * num2; 96 break; 97 case arithmetic.DIV: 98 Result = num1 / num2; 99 break; 100 default: 101 num1 = num2; 102 break; 103 } 104 105 //結果表示 106 textDisplay.Text = Result.ToString(); 107 isFirst = true; 108 109 if (textDisplay.TextLength >= 11) 110 { 111 textDisplay.Text = "Error"; 112 113 //エラー時、クリアボタン以外を無効化する 114 this.button0.Enabled = false; 115 this.button1.Enabled = false; 116 this.button2.Enabled = false; 117 this.button3.Enabled = false; 118 this.button4.Enabled = false; 119 this.button5.Enabled = false; 120 this.button6.Enabled = false; 121 this.button7.Enabled = false; 122 this.button8.Enabled = false; 123 this.button9.Enabled = false; 124 this.buttonEq.Enabled = false; 125 this.Dot.Enabled = false; 126 this.ADD.Enabled = false; 127 this.SUB.Enabled = false; 128 this.MUL.Enabled = false; 129 this.DIV.Enabled = false; 130 } 131 132 } 133 134 //クリアボタンを押したとき 135 private void Clear_Click(object sender, EventArgs e) 136 { 137 textDisplay.Clear(); 138 139 this.button0.Enabled = true; 140 this.button1.Enabled = true; 141 this.button2.Enabled = true; 142 this.button3.Enabled = true; 143 this.button4.Enabled = true; 144 this.button5.Enabled = true; 145 this.button6.Enabled = true; 146 this.button7.Enabled = true; 147 this.button8.Enabled = true; 148 this.button9.Enabled = true; 149 this.buttonEq.Enabled = true; 150 this.Dot.Enabled = true; 151 this.ADD.Enabled = true; 152 this.SUB.Enabled = true; 153 this.MUL.Enabled = true; 154 this.DIV.Enabled = true; 155 } 156 157 158 } 159}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2019/04/15 11:55

解決したならベストアンサーを選択してください。 完成までサポートするものではなく、一つの問題に対して一つの回答をするものです。
guest

回答3

0

ひょっとしたら、入力された計算式をまとめて計算する関数電卓的な動作にしたいのでしょうか?
Windowsの電卓の電卓モードと、関数電卓モードで1+2*3=を入力してみてください。
前者は9が、後者は7が返ってきます。
後者を実現するには文字列の計算式の計算結果を取得するが参考になると思います。

投稿2019/04/13 01:37

hihijiji

総合スコア4150

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

1+2+3のような、連続した計算のやり方がわかりません。

ご提示のコードは数字や演算子のボタンがたくさんありそうなのでコードを読んだ限りで、実際には試していないのですが、例えば「1 + 2 + 3 - 4 =」などと入力されるケースでは演算子の次の整数(または小数)が確定したときに答えを求めて表示してしまえば良いと思います。例えば、

  1. "1" が入力されたら(最初なので)ただ、変数v1(名前は何でも良いし、プロパティで可)に保存する。表示もする。
  2. "+" が入力されたら演算子なので、"+"を保存する。(既にarithmetic signで使っていますよね)
  3. "2" が入力されたら既に整数v1 に値が保存されてあり、演算子"+"もあるので計算可能な状態とみなせる。1 + 2 を計算して答え3 を表示する。**(表示タイミングは再考/この時点で表示してしまうと2桁以上の数値入力で破綻してしまうので不適切です - 追記をご覧ください)**3は引き続き次の計算に使うため、変数v1 に保存する。
  4. "+" が入力されたら演算子なので、"+"を保存する。
  5. "3" が入力されたら変数v1arithmetic signで示される"+"で 3 + 3 を計算し、答6 を表示する。6は、引き続き次の計算に使うため、変数v1 に保存する。
  6. "-" が入力されたら演算子なので、"-"を保存する。
  7. "4" が入力されたら変数v1arithmetic signで示される"-"で 6 - 4 を計算し、答2 を表示する。2は、引き続き次の計算に使うため、変数v1 に保存する。
  8. "=" が入力されたら、答え表示完了の為の色々な処理をする。(既に答えは表示されてるけど)

...以下同じ

整数や小数、演算子が入力されるごとに逐一「今現在、どんな状態で何ができるか」を意識して処理すると良いです。「状態遷移」の考え方です。一例として参考にしてみてください。


コメントを受けて追記しました:2019/04/13 11:06
※オリジナルの回答を大きく編集してしまうと、コメントでいただいた指摘事項の対応が分かりづらくなると思いましたので、編集は最低限にしました。

数値の範囲と入力確定の問題(Zuishinさんのご指摘より):

回答では数値として1桁だけのものを例示してしまいましたが、当然そんなものでは実用にならないわけで、考慮不足であったことは失礼しました。2桁以上入力すると破綻しますので、少なくとも数値の入力を確定するのは次の演算子(+, -, * , /, =)入力時点とすべきでしょう。

演算子の優先順位の問題(YAmaGNZさんのご指摘より):

簡単な四則演算をする電卓でも、演算子の優先順位(乗除は加減を優先)を考慮するものとしないものがあります。

(1) 演算子の優先順位を考慮する電卓
iPhone(iOS12.2)の「計算機」やAndroid(6.0.x)標準の「電卓」で確認したところでは、優先順位を意識した動きになっていて、常に数式の全体を見て、再計算されます。(私はこれは今回初めて知りました)

使ってみて面白いと思ったのは、例えばAndroidで表示領域が大きいものでは2桁以上の値を入力すると逐次に再計算される、と言うことです。
「1 + 23 * 45」の場合、「1 + 2 で 3を表示」「1 + 23 で 24を表示」「1 + 23 * 4 で 93を表示」で「1 + 23 * 45 で1036を表示」と遷移していきます。

いずれにせよYAmaGNZさんのご指摘のように、入力された数式を何らかの方法ですべて覚えていて、終わりを示す演算子の入力(例えば=)が無ければ答えは出ないということになります。面倒ですが、単語分割(トークナイズ)など様々な検討事項が増えて、プログラミングトピック的には面白いとは思います。

(2) 演算子の優先順位を考慮しない電卓
一般的な実物の電卓では優先順位は考慮せず、逐次に計算されるものが多いようです。例えば 「1 + 2 * 3 = 9」となります。(手持ちのCanon HS-2200Aで確認)関数電卓などでは違うかもしれません。回答では勝手にこの動きを想定してしまいましたが、質問者さんのケースではどちらかを動作仕様として意識する必要があるかと思います。

尚、Windows (7と10で確認)の「電卓」では、メニューで選択するところの「普通の電卓」でこの動きとなり、「関数電卓」と「プログラマ」では優先順位を考慮する動きになっています。

逐次に答えが完成する、と言う意味ではこちらの方が簡単ではあります。

本件と直接関係あるとは限りませんが、teratailでも「電卓」に関して過去、様々な質問回答があったようです。teratail「電卓」で検索するとたくさん出てきます。改めて考えると、プログラミングの課題(なのか分かりませんが)として適切なもののひとつなのかもしれません。

投稿2019/04/12 17:20

編集2019/04/13 02:07
dodox86

総合スコア9183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2019/04/12 22:39

1 + 21 を計算する時には 1 + 3 22 と表示されると思いますが、iPhone の計算機はそういう表示の仕方なんでしょうか?
YAmaGNZ

2019/04/12 22:50

質問者さんが求めているレベルが「1+2*3=」と入力された時、結果が9なのか7なのかで変わってきますが 前者であれば、3.の時点での演算ではなく、4.の時点で前に入力されたものを演算では? 後者であれば、式が確定するまで演算できないことになりますが
dodox86

2019/04/12 23:03

Zuishinさん、YAmaGNZさん、ご指摘どうもありがとうございます。そのとおりだと思います。投稿した後、「そもそも1桁しか対応できず、入力を阻害するな」と自分でも思いましたが、ご指摘をうけて改めてiPhoneの電卓と普通の電卓の動きを確認しました。回答のフローは思慮が足りませんでした。訂正させていただきます。
hihijiji

2019/04/13 01:28 編集

"1+2+3"でググると、とても面白い検索結果が出てきますね。 一時期iPhoneの電卓では、1+2+3=24 ってなる現象が発生したらしいです。 それを再現したいわけではないでしょうけど
dodox86

2019/04/13 01:32

様々な電卓を確認していて(少なくとも私にとって)色々なことが分かりました。大変興味深いです。
YAmaGNZ

2019/04/13 09:51

質問者さんの要望は前者のほうみたいですね。 それであれば、dodox86さんのおっしゃるように、状態遷移を考えて作っていけばいいかと思います。 https://blog.goo.ne.jp/masaki_goo_2006/e/d77c7b85b3dbc04b1b36cf88eaf57d73 こちらのように、キーを押したら、何がどう変わっていくか書き出すと分かりやすいかと思います。
退会済みユーザー

退会済みユーザー

2019/04/13 13:05

皆様ありがとうございます。 参考にさせていただき、考えてみたのですが理解ができておらず、どの部分にどのようなコードを書いたらいいのかがわかりません。 もう少しヒントをいただけないでしょうか。
退会済みユーザー

退会済みユーザー

2019/04/13 14:34

解決しました!!! 残りの修正は、ぼちぼちとやっていきます。 解答してくださった皆様、 本当にありがとうございました!!!
guest

0

とりあえず、現状のソースから修正するとすればです。
例えば、下記の+を押したときの処理ですが

C#

1//足し算 2private void ADD_Click(object sender, EventArgs e) 3{ 4 sign = arithmetic.ADD; 5 isFirst = true; 6}

2番目の数字の入力の後に押された時は、signがarithmetic.undefined以外になっているかと思います。
ですので、押された時にsign != arithmetic.undefinedの場合、=を押された時の処理を行い、その後1つ目の数字入力後の+が押された時の状態に移行すればいいことになります。

C#

1//足し算 2private void ADD_Click(object sender, EventArgs e) 3{ 4 if(sign != arithmetic.undefined) 5 { 6 //=の時の処理 7 } 8 sign = arithmetic.ADD; 9 isFirst = true; 10}

ただし、+が連続で押された場合などの、各ボタンが正しい手順以外の操作が行われた時のことが考慮されていないので、そういった操作を行われた場合は無視するなどの処理が必要になるかと思います。
ここでも状態遷移をしっかり管理しておかないと、正しい動作なのか、誤った操作なのかが判断できません。
その管理を行おうとすると、ソースの修正はかなり必要になってくるはずです。

投稿2019/04/13 14:04

YAmaGNZ

総合スコア10222

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問