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

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

ただいまの
回答率

90.50%

  • Java

    15810questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

四捨五入のプログラムでエラーが出て困っています

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 872

前提・実現したいこと

javaで四捨五入のプログラムを作っています。キーボードから四捨五入する値を入力して、四捨五入する位を入力すると結果が表示され、’n’を入力すると終了し、Enterやその他のキーが入力されると四捨五入する位を再びたずねて、値を入力すると四捨五入してくれるプログラムを作っています。

発生している問題・エラーメッセージ

1回目は正常に作動し、'n'を入力すると終了しますが、Enterや他のキーを入力すると
四捨五入する位を再びたずねて何も入力できないままエラーメッセージが表示されます。
以下が実行例です。(”nを入力すると終了します”のあとはEnterを入力した)


C:\Users\●●●●●\プログラミング>java RoundUp
四捨五入したい数を入力してください
36781.72
どの位を四捨五入しますか?
例)10000, .., 10, 1,  0.1, .., 0.0001
0.1
四捨五入した結果
36782.0
nを入力すると終了します

どの位を四捨五入しますか?
例)10000, .., 10, 1,  0.1, .., 0.0001
Exception in thread "main" java.lang.NumberFormatException: empty String
        at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source)
        at sun.misc.FloatingDecimal.parseDouble(Unknown Source)
        at java.lang.Double.parseDouble(Unknown Source)
        at RoundUp.main(RoundUp.java:22)

該当のソースコード

import java.io.*;
class RoundUp
{
    public static void main (String[] args) throws IOException
    {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    System.out.println("四捨五入したい数を入力してください");
    String str = br.readLine();

    int repeat = 0;
    do{
        // 変数初期化(2回目以降)
        double x = Double.parseDouble(str);
        double p = 0;

        // 四捨五入する位の入力と入力判定
        do{
          System.out.println("どの位を四捨五入しますか?");
          System.out.println("例)10000, .., 10, 1,  0.1, .., 0.0001");
          String str2 = br.readLine();
          double o = Double.parseDouble(str2);
          double n = 0.0001;
          for(int i = 0; i < 9; i++){
              if(o == n && o > 0){
              p = o;
              break;
              }
              n = n*10;
          }
          if(p == 0){
              System.out.println("例にならって入力してください");
          }
        }while(p == 0);

        // 正負による四捨五入の処理の場合分け
        int s = 1;
        if(x < 0) s = -1;

        // 四捨五入の処理
        x = (x + 5*p*s)/(10*p);
        int y = (int)x;
        double z = y*(10*p);

        // 結果表示
   System.out.println("四捨五入した結果");
   System.out.println(z);

        // nを入力で終了  Enterや他のキーが入力されると四捨五入する位を再指定させ再実行するようにしたい
        System.out.println("nを入力すると終了します");
        repeat = br.read();        
        }while(repeat != 'n');
    }
}

試したこと

System.out.println("nを入力すると終了します");
repeat = br.read();        
の2行を消しEnterを入力すると再び四捨五入する位をたずねて、値を入力すると四捨五入してくれるがもう終了したくても終了できない。

補足情報(言語/FW/ツール等のバージョンなど)

より詳細な情報

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

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

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

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • swordone

    2017/10/09 13:54

    ブロックごとにインデントを下げてください。

    キャンセル

回答 2

checkベストアンサー

+1

該当のコードでは、2回目以降の入力に限らず、最初の入力時にEnterのみを入力しても同様の例外が発生するのではないかと思われます。

発生箇所は、スタックトレースにも記載がありますが、下記のparseDoubleに数値として変換できない文字列が入力されるために発生しています。

String str2 = br.readLine();
double o = Double.parseDouble(str2);

これを回避するためには、以下の2点の修正が必要です。

  1. repeatで1文字取得している箇所を、1行の文字列として取得するようにする。
  2. parseDoubleで変換に失敗した場合の処理を追加する。

修正例としては下記のようになります。
このコードでは、最初のString str = br.readLine();でも数値に変換できない値が入力された場合、同じようにNumberFormatException例外が発生しますので、対応方法を考えてみられるとよいかと思います。

import java.io.*;
class RoundUp
{
    public static void main (String[] args) throws IOException
    {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        System.out.println("四捨五入したい数を入力してください");
        String str = br.readLine();

        String repeat = "";
        do{
            // 変数初期化(2回目以降)
            double x = Double.parseDouble(str);
            double p = 0;

            // 四捨五入する位の入力と入力判定
            do{
                try {
                    System.out.println("どの位を四捨五入しますか?");
                    System.out.println("例)10000, .., 10, 1,  0.1, .., 0.0001");
                    String str2 = br.readLine();
                    double o = Double.parseDouble(str2);
                    double n = 0.0001;
                    for(int i = 0; i < 9; i++){
                        if(o == n && o > 0){
                            p = o;
                            break;
                        }
                        n = n*10;
                    }
                    if(p == 0){
                        System.out.println("例にならって入力してください");
                    }
                } catch (NumberFormatException e) {
                    System.out.println("数値以外が入力されました");
                    p = 0;
                }
            }while(p == 0);

            // 正負による四捨五入の処理の場合分け
            int s = 1;
            if(x < 0) s = -1;

            // 四捨五入の処理
            x = (x + 5*p*s)/(10*p);
            int y = (int)x;
            double z = y*(10*p);

            // 結果表示
            System.out.println("四捨五入した結果");
            System.out.println(z);

            // nを入力で終了  Enterや他のキーが入力されると四捨五入する位を再指定させ再実行するようにしたい
            System.out.println("nを入力すると終了します");
            repeat = br.readLine();        
        }while(repeat != "n");
    }
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

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

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

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/09 14:19

    回答ありがとうございます!
    上記の修正例で実行してみたところ以下のようにエラーメッセージがでました。
    RoundUp2.java:56: エラー: 不適合な型: Stringをintに変換できません:
    repeat = br.readLine();
    ^
    RoundUp2.java:57: エラー: 型intとStringは比較できません
    }while(repeat != "n");

    そこでrepeatをint型からString型にしてみたところ上手くいきました。ありがとうございます!

    キャンセル

  • 2017/10/09 18:35 編集

    結果的には想定の動作となったようでなによりです。
    ご指摘の部分はこっそり直しておきました。
    実行していないのがばれてしまいましたね。

    キャンセル

  • 2017/10/09 18:37

    repeat != "n"なんて、永遠に成立してしまう無限ループなのでは

    キャンセル

  • 2017/10/09 18:38

    キャンセル

0

何も入力せずEnterを押した場合、入力には改行文字CR(U+000D)が1文字のみ入っている状態になります。
この状態でrepeat = br.read();が実行された場合、repeatには13が入ります。
これで次のループのString str2 = br.readLine()が実行されると、もう残っている入力がないため、str2は空文字になります。これをparseDoubleしようとしたためエラーになります。

余談ですが、doubleで丸めを行うのは不向きなので、BigDecimalを使ったほうがいいです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

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

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

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • Java

    15810questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。