java 電卓プログラム
解決済
回答 2
投稿
- 評価
- クリップ 1
- VIEW 7,768

退会済みユーザー
前回から少しだけ前進しましたが、まだ壁にぶつかっているのでご助力お願いいたします。
表記イメージとしては、実行するとまずは下記が表示されます。
C\JAVA>java Dentaku
現在の値:0
演算子:
入力された値:
数値を入力してください >>
実際に入力開始後のイメージ↓
現在の値:0
演算子:
入力された値:
数値を入力してください >>1
↓
現在の値:1
演算子:
入力された値:
演算子を入力してください >>+
↓
現在の値:1
演算子:+
入力された値:
数値又は演算子を入力してください >>60
↓
現在の値:1
演算子:+
入力された値:60
数値又は演算子を入力してください >>
"E"が入力されるまでずっとループ。
現在出来ているコード
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
public class Dentaku {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// フィールド変数初期化
String now = "0";
String enzan = "";
String input = "";
String msg = "数値";
while(true){
System.out.println("現在の値:" + now);
System.out.println("演算子:" + enzan);
System.out.println("入力された値:" + input);
System.out.print(msg + "を入力してください >>");
String data = br.readLine();
System.out.println();
// eを入力されたらループ終わり
if ("e".equals(data)) {
break;
}
// cを入力で起動時の状態へ
if ("c".equals(data)) {
now = "0";
enzan = "";
input = "";
msg = "数値";
data = "";
}
if ("=".equals(data)) {
if ("+".equals(enzan)){
BigDecimal bd1 = add(now, input);
now = bd1.toString();
} else if ("-".equals(enzan)){
BigDecimal bd2 = subtract(now, input);
now = bd2.toString();
} else if ("*".equals(enzan)){
BigDecimal bd3 = multiply(now, input);
now = bd3.toString();
} else if ("/".equals(enzan)){
try {
BigDecimal bd4 = divide(now, input);
now = bd4.toString();
} catch (ArithmeticException e) {
System.out.println("0で割ることは出来ません");
}
}
enzan ="";
data = "";
}
if ("ce".equals(data)) {
/*直前の入力をクリア*/
}
try {
if ("数値".equals(msg)) {
now = data;
msg = "演算子";
} else if ("演算子".equals(msg)) {
enzan = parseEnzan(data);
msg = "数値又は演算子";
} else {
if (is_Enzan(data)) {
enzan = parseEnzan(data);
} else {
input = data;
}
msg = "数値又は演算子";
}
} catch(Exception e) {
System.out.println(msg + "ではありません");
}
}
}
// str が演算子か否かチェック
static boolean is_Enzan(String str) {
if ((str.length() != 1) || ("+-*/".indexOf(str) == -1)) {
return false;
}
return true;
}
// str が演算子でなければ、例外発生
static String parseEnzan(String str) throws IllegalArgumentException {
if (is_Enzan(str) == false) {
throw new IllegalArgumentException("演算子でありません。");
}
return str;
}
static BigDecimal add(String num1, String num2){
return new BigDecimal(num1).add(new BigDecimal(num2));
}
static BigDecimal subtract(String num1, String num2){
return new BigDecimal(num1).subtract(new BigDecimal(num2));
}
static BigDecimal multiply(String num1, String num2){
return new BigDecimal(num1).multiply(new BigDecimal(num2));
}
static BigDecimal divide(String num1, String num2){
return new BigDecimal(num1).divide((new BigDecimal(num2)), 20, BigDecimal.ROUND_HALF_UP);
}
}
___________________
①if ("c".equals(data)) {
で最初の表示画面にしたいが、現状だとnow:cとなってしまい上手くいかない。
②nowに文字を入れても動作してしまう(aadcなどでも通ってしまう)が、数字でなければエラーを出したい。
以上二点をどうすればよいか教えてください。
よろしくお願いいたします。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+3
前回の質問を探すためにプロフィールをみたところ勉強中ということで、単純に質問の内容だけを答えさせてもらいます。(あえて、他の部分には口をだしません)
①if ("c".equals(data)) {
で最初の表示画面にしたいが、現状だとnow:cとなってしまい上手くいかない。
これに関しては単純です。
各if文が別れてしまっているからです。
if ("e".equals(data)) {
//略
}else if ("c".equals(data)) {
//略
}else if ("=".equals(data)) {
//略
}else if ("ce".equals(data)) {
//略
}else{
try {
if ("数値".equals(msg)) {
now = data;
msg = "演算子";
} else if ("演算子".equals(msg)) {
enzan = parseEnzan(data);
msg = "数値又は演算子";
} else {
if (is_Enzan(data)) {
enzan = parseEnzan(data);
} else {
input = data;
}
msg = "数値又は演算子";
}
} catch(Exception e) {
System.out.println(msg + "ではありません");
}
}
というようにelseをつかって"C"が入力された時には処理が行われないようにしましょう。
現状ではelseがないためmsgが"数字"のに設定されたままtryの中にある条件式に処理が行くようになっています。
②nowに文字を入れても動作してしまう(aadcなどでも通ってしまう)が、数字でなければエラーを出したい。
nowに文字を入れても・・とありますが、条件式("数値".equals(msg))の時にnow=dataとしています。
単純に回答をするとその条件の時にdataが数字がどうか判定すればよいです。
if("数値".equals(msg)){
if(/*dataが数字かどうかの判定*/){
now=data;
msg="演算子"
}else{
//数字じゃなかった場合の処理
}
}
数字かどうかの判定はteratailを探せば幾つか出てくるみたいなので勉強してみてください。
いくつか方法はあります。
余談ですが
"+-*/".indexOf(str) == -1
この文は「あ、なるほど・・・」と思ったやり方です。
私はすぐにPattern等を使って判定を始めてしまうため頭が固くなっているなぁと感心しました。
勉強頑張ってください。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
"c".equals(data)...
普通は、
オブジェクト.equals( "c" )
見たいにするのでは?
2は私は発想を変えて、
文字列で受けてint型に変換できなければ false ( あるいは例外を投げる ) とします。
たとえば、取得用クラス&メソッドを作り、
String型でいったん取得して、
int型に変換してみる。
で、NumberFormatException っていう例外が発生したら、
数字以外があるってことなので、
再度例外を投げる ( or false を返す ) とか。
あ、でも、計算で、"+", "-", "/" ... と計算で使う記号もあるので、
文字列として取得 -> 変換できればその数値を返し、できなければ 数字以外とみなす -> 数字以外のとき、指定記号 ( "+", "-", "/", "*"... ) のときも true とみなす ( つまりOK ということ。 )
みたいに、
int型に変換して、できたらtrue, できなければ 指定記号でなければ false とか。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.34%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2016/05/13 00:19
①も②も私のレベルまで下げて丁寧に解説いただいたおかげでとても良く理解出来ました、本当にありがとうございます。
(やはり他の部分にも多々ツッコミどころがあるようですが;;まずは現時点の疑問を解消すべく頑張ります;)
"+-*/".indexOf(str) == -1についてもお褒めいただきありがとうございます!
ちょうどindexOfというメソッドを使ってみたばかりだったので、これで出来るかな?と再び使用してみました…勉強頑張ります、ありがとうございます!