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

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

新規登録して質問してみよう
ただいま回答率
85.35%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

Java

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

while

Whileは多くの言語で使われるコントロール構造であり、特定の条件が満たされる限り一連の命令を繰り返し実行します。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

Q&A

1回答

1705閲覧

[Java]CSVファイル 月ごとの時間算出方法

koumm

総合スコア1

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

Java

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

while

Whileは多くの言語で使われるコントロール構造であり、特定の条件が満たされる限り一連の命令を繰り返し実行します。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

0グッド

0クリップ

投稿2020/10/21 14:54

前提・実現したいこと

CSVファイルを読み込み、月ごとの所要時間の合計を
算出するプログラムを作成しています。

while文の処理がうまくいかず、無限ループから抜け出せずに
困っています。
丸投げのような質問となってしまい申し訳ありませんが
ヒントをいただけたらと思います。
よろしくお願いします。

【CSVファイルイメージ】
7月1日,6
7月2日,11
7月3日,0
8月1日,9.4
8月2日,11
8月3日,0
・・・

【出力イメージ】
7月17
8月20.4

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

無限ループになってしまう。

該当のソースコード

import java.io.*; class Test{ public static void main(String[] args) { String line; String[] data; String month = ""; double monthlyTotal = 0; BufferedReader reader = null; try{ reader = new BufferedReader(new FileReader("test.csv")); line = reader.readLine();//最初の1行を読む while(line != null) { if(line.contains("月") && line.contains("日")){ data = line.split(","); if(month.isEmpty()){ month = data[0].substring(0,data[0].indexOf("月")); } //同じ月の中のループ while(line.substring(0,data[0].indexOf("月")).equals(month)){ if(!data[1].isEmpty()) { monthlyTotal += Double.parseDouble(data[1]); } month = data[0].substring(0,data[0].indexOf("月"));   //次行の読み込み line = reader.readLine(); data = line.split(","); } System.out.println(month + "月" + monthlyTotal); monthlyTotal = 0; //data = line.split(","); if(!data[1].isEmpty()) { monthlyTotal += Double.parseDouble(data[1]); } } } System.out.println(month+ "月" + monthlyTotal); }catch(IOException e) { e.printStackTrace(); }finally { try { if(reader != null) { reader.close(); } }catch(IOException e){} }  } }

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

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

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

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

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

guest

回答1

0

丸投げのような質問となってしまい申し訳ありませんが
ヒントをいただけたらと思います。

丸投げとまでは思いませんが。「ヒントを...」ということなので、現状のコードの致命的な問題点、要は永久ループしてしまう原因と、考え方のヒントのみ示させていただきます。最初のwhileループの前に最初の1行を読んでいますが、それ以降、次の行を読む操作は「同じ月の中のループ」のwhileの中でだけ行われています。違う月のデータになったらスキップしてしまうので、永久ループになってしまいます。

Java

1// 抜粋 2... 3 line = reader.readLine();//最初の1行を読む 4 while(line != null) { 5 if(line.contains("月") && line.contains("日")){ 6 data = line.split(","); 7 if(month.isEmpty()){ 8 month = data[0].substring(0,data[0].indexOf("月")); 9 } 10 //同じ月の中のループ 11 12//※1: 同じ月のデータしか扱わないので、下のwhileには入らない 13 while(line.substring(0,data[0].indexOf("月")).equals(month)){ 14 if(!data[1].isEmpty()) { 15 monthlyTotal += Double.parseDouble(data[1]); 16 } 17 month = data[0].substring(0,data[0].indexOf("月")); 18   //次行の読み込み 19 20//※2: ここでしか次の行を読んでいない 21 line = reader.readLine(); 22 data = line.split(","); 23 } 24

必ず次のデータを読むような操作、つまりここではline = reader.readLine();ですが、特殊な条件でのみそれを実行するようなプログラムにすると場当たり的なフローになり、バグを生みやすいです。そんな場合は1ヶ所でだけ呼ぶようにし、その後の条件でデータを操作していきます。例えば、質問者さんの今のコードを踏襲すると、おおむね以下のような疑似コードで示すフローになると思います。(あえて完成したコードは載せません)尚、入力のCSVファイルの行データとしては同じ月のデータが連続していることを想定していますが、そうではない場合は月をキーとして扱うなど、別の方法も色々考えられます。

while (全行を読み終えるまでループ) { 1行読む if (前の行と比べて月が替わった) { 月の合計を出力 次の対象とする月を更新 月の合計を初期化 } else { 月の合計を加算 } } 出力していない月の合計があれば出力

質問の主旨とは離れますが、コードのインデント(字下げ)は揃えましょう。それだけでフローの判り易さが変わります。言い方を変えると、インデントが崩れたままだと自分で書いたものでも間違えたフローで考え続けがちです。小さなことですが、気に留めてコーディングしましょう。

投稿2020/10/22 05:08

編集2020/10/22 06:15
dodox86

総合スコア9256

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問