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

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

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

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

Q&A

解決済

C# 電卓アプリ作成 計算後の値をクリア

migio
migio

総合スコア45

C#

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

3回答

0グッド

0クリップ

1115閲覧

投稿2022/07/15 12:03

環境:VisualStudioのFormアプリ.NET6.0

C#を用いて電卓アプリの作成を行っています。
四則演算及びクリアキーのコーディングを終えたのですが、以下の実装が出来ておりません。

①計算後、数字を入力した際に値をクリアして入力
例) 3 + 3 = "6" ⇒ "1"を入力した際に"61"となってしまいますが、実際は"1"と表記させたいです

②ラベルに表記される値を3桁毎に区切る
一つ一つのイベントに実装するのではなく、クラスにコーディングしたいと考えています。

C#

1 public partial class Form1 : Form 2 { 3 4 // 四則演算代入 5 String Oper = ""; 6 7 // 最初に入力する値 8 double num1 = 0; 9 10 // 2度目に入力する値 11 double num2 = 0; 12 13 public Form1() 14 { 15 InitializeComponent(); 16 } 17 18 private void Form1_Load(object sender, EventArgs e) 19 { 20 21 } 22 23 private void ButtonNumber_Click(object sender, EventArgs e)// 数字の番号を押した時 24 { 25 // 数値の入力 後方への追加 26 String text = labelResult.Text + ((Button)sender).Text; 27 28 // String型の変数textをdouble型の変数Nに変換 29 double N = Convert.ToDouble(text); 30 31 // double型の変数NをString型の変数text2に変換 最初のtext0を削除 32 String text2 = N.ToString(); 33 34 // 0を削除した上で数値をlabelResultに入力 35 // 3桁ごとに","を実装 36 labelResult.Text = String.Format("{0:#,0}",text2); 37 38 } 39 40 private void ButtonAllClear_Click(object sender, EventArgs e) 41 { 42 // labelResultに入力された値を削除 43 labelResult.Text = ""; 44 } 45 46 47 private void buttonPoint_Click_1(object sender, EventArgs e) // 小数点を押した時 48 { 49 // 小数点が一度使われていれば 50 if (labelResult.Text.IndexOf(".") >= 0) 51 { 52 //入力せずに戻る 53 return; 54 } 55 //labelResultに"."を入力 56 labelResult.Text = labelResult.Text + "."; 57 } 58 59 private void buttonOperator_Click(object sender, EventArgs e) // ÷×−+ のボタンを押した時 60 { 61 // 四則演算記号の代入 62 Button btn = (Button)sender; 63 64 // 演算方法の選択 65 switch (btn.Text) 66 { 67 68 case "÷": 69 Oper = "÷"; 70 break; 71 72 case "×": 73 Oper = "×"; 74 break; 75 76 case "+": 77 Oper = "+"; 78 break; 79 80 case "-": 81 Oper = "-"; 82 break; 83 84 } 85 86 // labelResult.Textの値をnum1に入力 87 num1 = double.Parse(labelResult.Text); 88 89 // labelResult.Textの値を0に 90 labelResult.Text = "0" ; 91 } 92 93 private void buttonEqual_Click(object sender, EventArgs e) // = ボタンを押した時 94 { 95 // labelResult.Textをdouble型に変換 96 num2 = double.Parse(labelResult.Text); 97 98 // 計算結果Resultを定義 99 double Result = 0;  100 101 // 四則演算パターン 102 if (Oper == "÷") 103 { 104 Result = num1 / num2; 105 } 106 else if (Oper == "×") 107 { 108 Result = num1 * num2; 109 } 110 else if (Oper == "-") 111 { 112 Result = num1 - num2; 113 } 114 else if (Oper == "+") 115 { 116 Result = num1 + num2; 117 } 118 119 if (Result >= 9999999999999999) 120 121 { 122 labelResult.Text = "9999999999999999999"; 123 } 124 else if (Result <= 9999999999999999) 125 { 126 // ResultをlabelResult.Textに代入 127 labelResult.Text = Result.ToString(); 128 129 } 130 131 132 133 134 } 135 136 private void buttonInversion_Click(object sender, EventArgs e) 137 { 138 String inv = labelResult.Text; 139 double Inv = Convert.ToDouble(inv); 140 Inv = Inv * (-1); 141 labelResult.Text = Inv.ToString(); 142 143 } 144 145 private void ButtonClear_Click(object sender, EventArgs e) 146 { 147 labelResult.Text = Convert.ToString(num1); 148 } 149 }

以上2点に関してご指導ご鞭撻いただけますと幸いです。
よろしくお願いいたします。

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

YAmaGNZ

2022/07/15 12:13

「3桁毎に区切る」とは1,000といった感じでカンマ区切りを行うのですか? それとも1 000といった感じにスペースで区切るとかなんですか? 「クラスにコーディング」とはどういうことを指しているのでしょうか? イベントハンドラに実装しても、フォームもクラスなので「クラスにコーディング」と言えますけど・・・
migio

2022/07/15 23:44

YAmaGNZさま 不足があり申し訳ありません。 イベントハンドラへの実装を意味しています。 また、表記については"1,000,000,000"のような表記を想定してご質問させていただきました。

回答3

3

ベストアンサー

①計算後、数字を入力した際に値をクリアして入力

電卓のようなプログラムを作る際、状態遷移図、もしくは状態遷移表を作るといいです。

「テストでバグ発見!(5)電卓プログラムに潜むバグ【出題編】」
https://monoist.itmedia.co.jp/mn/articles/2111/17/news009.html
https://monoist.itmedia.co.jp/mn/articles/2111/17/news009_2.html
https://monoist.itmedia.co.jp/mn/articles/2111/17/news009_3.html

2ページ目の状態遷移表がわかりやすいです。

状態(ステータス)として3つを上げていますが、市販の電卓と動きが違うので、もう一つ状態を加えるといいかなと思います。

S1 数値1入力中
S2 演算子入力後の入力待ち
S3 数値2入力中
S4 演算実行後、入力待ち

(1) プログラムが起動すると、S1 になります。
(2) 数字ボタンを入力している間は S1 のままラベルを編集する処理を行います。
(3) 演算子のボタンが押されたら、演算子と、現在ラベルに表示されている値を保存します。状態は S2 に移ります。
(4) S2 では、数字のボタンが押されたら、それをラベルに表示します。状態は S3 に移ります。
(5) 数字ボタンを入力している間は S3 のままラベルを編集する処理を行います。
(6) 「=」ボタンが押されたら、(3) で保存した演算子と数値、現在ラベルに表示されている値を使って演算を行い、演算結果をラベルに表示します。状態はS4 に移ります。
(7) 数字ボタンが押されたら、ラベルに表示し、S1 に移ります。

通常の処理は(1)~(7) になりますが、(6) で演算子ボタンが押されたら演算処理を行いますが、演算子と演算結果を保存し、状態は S2 に移ります。
こんな感じで表を埋めてからプログラムにとりかかると迷いなくコーディング出来ると思います。

追記

②ラベルに表記される値を3桁毎に区切る

これは意外にむずかしいです。
というのは、下手に編集しちゃうと小数点を入力したとき、1,000.0 も 1,000.00 も区別がつかなくなるからです。
小数点以下の桁数を調べ、編集式を変えます。
メソッドを作っていちいちコールするのは面倒なので計算結果表示用のラベルを作成します。

C#

1internal class ResultLabel : Label 2{ 3 public override string Text { 4 get { 5 return base.Text; 6 } 7 set { 8 if (value == null) { 9 value = string.Empty; 10 } 11 if (decimal.TryParse(value, out decimal decimalValue)) { 12 int decimalPosition = value.IndexOf('.'); 13 if (decimalPosition == -1) { 14 base.Text = decimalValue.ToString("#,##0"); 15 } else { 16 int decimalDigits = value.Length - decimalPosition - 1; 17 if (decimalDigits > 0) { 18 string formatString = "#,##0." + new string('0', decimalDigits); 19 base.Text = decimalValue.ToString(formatString); 20 } else { 21 base.Text = decimalValue.ToString("#,##0") + "."; 22 } 23 } 24 } else { 25 base.Text = value; 26 } 27 } 28 } 29}

投稿2022/07/15 23:48

編集2022/07/16 09:43
KOZ6.0

総合スコア2252

dodox86, migio, usekay👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

migio

2022/07/16 05:35

ご回答いただきありがとうございます。 参考とさせていただきます。
KOZ6.0

2022/07/16 09:44

②に対する回答を追記しました。

2

私なら「イコール(=)が入力されたかどうか」を管理すると思います。

例えばprivateなプロパティとしてbool equalbuttonPushedを用意して、これをデフォルトではfalseとしておく。(押されてないから)

そしてイコールが押された時にequalbuttonPushedをtrueにする。

で、数字が入力されたとき、equalbuttonPushedがtrueのときは表示されてる数字を破棄して新しく表示し、falseにする。(処理したため)

数字が入力されたときにequalbuttonPushedがfalseなら末尾に追加する感じになる。

こうすればイコール後の表示を変えることができるはず…

投稿2022/07/15 23:32

BeatStar

総合スコア4953

migio, usekay👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

migio

2022/07/16 05:35

ご回答いただきありがとうございます。 参考にさせていただきます。

0

一個前の入力を記録しておく。
前回の入力が=で今回の入力が四則演算記号以外なら全部リセットする。
他の機能(メモリー)などを考えなければまずこれで計算後の値の末尾に数字を繋げずにすみますね。

投稿2022/07/15 12:50

usekay

総合スコア388

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

Zuishin

2022/07/15 23:41

1 + 2 + を押した時、通常の電卓であれば合計の 3 もしくは最後の 2 が表示されると思います。 これに続けて 5 を押した時、この回答のアルゴリズムであれば 35 または 25 になりませんか?
Zuishin

2022/07/15 23:57

それ以前に、1 + 2 の段階で 12 になりますか。
migio

2022/07/16 05:36

ご回答いただきありがとうございます。 参考にさせていただきます。

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

ただいまの回答率
86.02%

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

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

質問する

関連した質問

同じタグがついた質問を見る

C#

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