Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

ファイルを読み込んで複数の配列に格納

[問題番号、ヒントの番号、レベル、ヒントの内容]を記述したファイルを読み込んで、配列にどんどん入れていきます。ヒントの内容が複数行になるので、ヒントの内容の終わりを示すための「/」がきたら、次に書かれている[問題番号、ヒントの番号、レベル、ヒントの内容]を配列に格納するようにしたいのですがうまくいきません。



以下が読み込むファイルになります。
ファイル名:student.txt

ex1,000,h,----------sample0(line1)--------------
----------sample0(line2)--------------
----------sample0(line3)--------------
----------sample0(line4)--------------/
ex1,001,m,----------sample1(line1)--------------
----------sample1(line2)--------------
----------sample1(line3)--------------
----------sample1(line4)--------------
----------sample1(line5)--------------/
ex1,002,l,----------sample2(line1)--------------
----------sample2(line2)--------------
----------sample2(line3)--------------
----------sample2(line4)--------------
----------sample2(line5)--------------
----------sample2(line6)--------------
/


************************

以下が未完成のプログラムになります。
ファイル名:FileRead.java

import java.io.*;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class FileRead {
    private static final int MAX = 200;

    public static void main(String[] args) {
        String line;
        String[] ExNum;
        String[] SampNum;

        String[] Level;

        String[] Sample;
        try {
            FileReader in = new FileReader("student.txt");
            BufferedReader br = new BufferedReader(in);
            // String line;
            int i = 0;

            ExNum = new String[MAX];
            SampNum = new String[MAX];
            Level = new String[MAX];
            Sample = new String[MAX];

            while ((line = br.readLine()) != null) {
                // System.out.println(line);

                ExNum[i] = line.substring(0, 3);
                SampNum[i] = line.substring(4, 7);
                Level[i] = line.substring(8, 9);

                Sample[i] = line.substring(10, line.indexOf('/'));
                System.out.println("ExNum: "+ExNum[i]);
                System.out.println("SampNum: "+SampNum[i]);
                System.out.println("Level: "+Level[i]);
                System.out.println("Sample: " + Sample[i]);
                i++;

            }

            br.close();
            in.close();

        } catch (IOException e) {
            System.out.println(e);

        }

    }
}







だれかわかる方、よろしくお願いします。

32

回答

7713

閲覧

32件の回答

評価

0

そうか、もうこんな季節なんだね。

来年がんばれ。(o・∀・)o

評価

0

ガイドラインは読んだ?

評価

0

>$さん
すみません。
検索でとんできてそのまま質問してしまったので、今読んでみました。

評価

0

うん、でも「読んでみました」というのを期待してたわけじゃなくて…。

読んだ結果、自分の質問はどうだったかを考えてほしかったなと。

質問自体は誰でもしていいんだけど、それなりの書き方でないと答えを得にくい。
質問するのが自由なように、どれにどう答えるかも読む人間の自由なんだから。

評価

0

>$さん
ご迷惑をかけてすみませんでした。


もう一度質問したい内容をまとめてみました。
ReadLineで1行ずつファイルの中身を読み込んでいるのですが、複数行になってしまう[ヒントの内容]をうまく配列に格納する方法を教えてほしいです。

評価

0

>うまくいきません。
くわしく。

答えそのものを教えてもらうよりも、自分のやってみたことを見てもらって、何がいけなかったかを知るほうが勉強になるよ。

評価

0

はい、頼りすぎた質問をしないでもっと自分でもがんばります。


配列に入れたものをそれぞれ表示するようにしたのですが、ヒントの内容が複数行あるせいかエラーのみしか表示されませんでした。
表示されたエラーはこれです。
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -11
    at java.lang.String.substring(Unknown Source)
    at FileRead.main(FileRead.java:36)

評価

0

次のステップはその例外について調べてみること。

評価

0

1行目に存在しない文字に対しての処理を
Sample[i] = line.substring(10, line.indexOf('/'));
と記入していたため例外が表示されたことがわかりました。

評価

0

文字が存在しないのに処理しようとしたからまずい。
では、文字が存在しなければ処理しなければ良い。

評価

0

んー
では、改行ありの文字列を配列に格納するためにはこの処理ではなくなにか別の処理を加える必要があるんですね。

評価

0

この処理の前に、「'/'が存在したら以降の処理を行う。存在しなかったら○○○…」という処理があればいいんじゃないでしょうか?

評価

0

惜しいところまでいきました。

                if(line.contains("/")){
                    Sample[i] = line.substring(0, line.indexOf('/'));
                    System.out.println("Sample: " + Sample[i]);
                }else{
                    ExNum[i] = line.substring(0, 3);
                    SampNum[i] = line.substring(4, 7);
                    Level[i] = line.substring(8, 9);
                    System.out.println("ExNum: "+ExNum[i]);
                    System.out.println("SampNum: "+SampNum[i]);
                    System.out.println("Level: "+Level[i]);
                    i++;
                }

評価

0

その処理だと、"/"のない行全てに対して[問題番号、ヒントの番号、レベル、ヒントの内容]が切り取られますよ。
本来2・3行目はヒントの内容しかないのに、問題番号、ヒントの番号、レベルを切り取ろうとしています。
■1〜3行目のヒントも4行目のように表示するには?
■データが","で区切られていることを生かせないでしょうか?
そこまで行けると、ゴールが近いと思います。

ところでこのif-else文、while文のカッコに入ってるという認識で良いのですよね?

評価

0

・現在処理しているのがヒントの行かそうでないか

という判定を考えてみよう。

評価

0

惜しいところまでいきました。

            arr = new String[MAX];
            for(int i=0;(line=br.readLine())!=null;i++){
                arr = line.split(",");
                for(int j=0;j<arr.length;j++){
                    if((arr[j].length())>3){
                        System.out.println("Sample:" + arr[j]);
                    }else{
                        System.out.println("ExNum:" + arr[j]);
                        System.out.println("SampNum:" + arr[j+1]);
                        System.out.println("Level:" + arr[j+2]);
                        break;
                    }
                }
            }

"/"を利用していない・・・。

恋きんぐ氏へ
期待していた名前でうれしいです。

評価

0

良い線まできたようですね。
ただ、このままだと1行目のヒント部分が出力されないと思うのですが…

「惜しい」と言うだけでなく「どう直したいのか」を教えてもらえると、
回答者も答えやすいですね。
あとは出力内容=求めている表示内容にするだけだと思いますので。

名前、ご希望に添えたようで幸いです。
偶然知り合いにあだ名が“たぬー”の人がいたもので、
ちょっと調子に乗ってみました (・ω・)

評価

0

>arr = new String[MAX];
new String[MAX]は余計。
splitした時点で配列が作られて、上書きされてしまう。

ところで、ヒントには , は入らないのかな?
例えば英文ヒントで1行にカンマがたくさん入っていたら、それだけで誤認してしまう。

そうでなくて、

>・現在処理しているのがヒントの行かそうでないか

というのは、「あるかないか」なんだからフラグ、つまりbooleanだということ。

booleanの初期値が「ヒントでない行」を示すようにして、1行読み込んだら「ヒントの行」に変える。
ヒントの行を処理中、末尾に / がある行が見つかったら「ヒントでない行」を示すように変える。

評価

0

用事があってPC開く時間がなかったので、いまやっと戻ってきたら。。。こんなにたくさんのやりとりが(;ω;)
いろいろな方法で試していて勉強になりました!
みなさん、本当にありがとうございます。


>ところで、ヒントには , は入らないのかな?

ヒントは文章をかいたりプログラムをかいたりする予定なので,も入っています。なので/を判定条件にしていました。

評価

0

ん?

>arr = line.split(",");

>if((arr[j].length())>3){

って、,の数を判定条件にしてるでしょ。
ヒントに , が入ればこの判定がtrueになっちゃうってことを言いたかったんだけど、大丈夫かな…。

行がどこまで続くか分からない場合に良くEOFに使われるのは、. 一文字とか空白行とか、"<EOF>"という文字列とか、ランダムな十六進数文字列とか。
いずれにしても本来の行とは別に、区切りだけの行を作ることが多いね。

評価

0

紛らわし名前で申し訳ないです。
私はたぬー (・ω・)氏ではありません。

入出力の勉強をしていて、自身も気になったので、
意見を頂こうと投稿してしまいました。

(>ω<);

評価

0

すっかり同一人物だと思ってたよw

評価

0

すっかり同一人物だと思ってたよw

評価

0

$さんに同じくですw

>入出力の勉強をしていて、自身も気になったので、
>意見を頂こうと投稿してしまいました。
こういう流れ、良いと思います(私だけ?)
問題をみんなで協力して解決出来るのが
掲示板の良いとこだと思うので!

一石二鳥スレ(?)みたいになってたみたいですが
たぬー (・ω・)さんもたぬきんぐさんも解決出来たのであればこれ幸いです。

評価

0

自分がいない間にたぬきんぐ氏が挑戦していてくれて、ホントに嬉しかったです!!

>ヒントに , が入ればこの判定がtrueになっちゃうってことを言いたかったんだけど、大丈夫かな…。

大丈夫です。理解できています!
,を条件にすると途中で切れてしまうので、以前に恋さんが提案してくれた「この処理の前に、「'/'が存在したら以降の処理を行う。存在しなかったら○○○…」という処理があればいいんじゃないでしょうか?」という意見をもとにプログラムを考えています。

評価

0

で、ヒントの文中や末尾に / は絶対にないの?

評価

0

>で、ヒントの文中や末尾に / は絶対にないの?

半角の/で作成しようと思っていたのですが、プログラム中に/が入ってしまうこともあると気づいたので、全角の/に変更することにしました。

評価

0

全角の/は入らないの?

だから、最初から書いてるように「ある文字が含まれている」という判断ではだめだって。

評価

0

ヒントの部分をまだ配列に入れていないのですが、$さんの回答をもとに考えて、表示はうまくいきました!
全角スラッシュおよび、フラグを立てやすくするために読み込むファイルも少し変更しました。


<student.txt>
ex1,000,h,
----------sample0(line1)--------------
----------sample0(line2)--------------
----------sample0(line3)--------------
----------sample0(line4)--------------/
ex1,001,m,
----------sample1(line1)--------------
----------sample1(line2)--------------
----------sample1(line3)--------------
----------sample1(line4)--------------
----------sample1(line5)--------------/
ex1,002,l,
----------sample2(line1)--------------
----------sample2(line2)--------------
----------sample2(line3)--------------
----------sample2(line4)--------------
----------sample2(line5)--------------
----------sample2(line6)--------------/



<訂正したプログラム>

while ((line = br.readLine()) != null) {

                if (flag == 0)// ヒント以外の行
                {
                    ExNum[i] = line.substring(0, 3);
                    SampNum[i] = line.substring(4, 7);
                    Level[i] = line.substring(8, 9);

                    System.out.println("ExNum: " + ExNum[i]);
                    System.out.println("SampNum: " + SampNum[i]);
                    System.out.println("Level: " + Level[i]);
                    System.out.println("Sample: ");
                    //Sample[i] = line.substring(10, line.length());
                    // System.out.println("Sample: " + Sample[i]);

                    flag = 1;
                    i++;
                    continue;
                }
                if (flag == 1) {// ヒントの行
                    // Sample[i] = line.substring(10, line.indexOf('/'));
                    
                    System.out.println(line.substring(0, line.length()));

                    if (line.indexOf('/') > 0) {         
                System.out.println(" ");
                        flag = 0;
                    }
                }
                i++;

            }


評価

0

>if (flag == 0)// ヒント以外の行
>if (flag == 1) {// ヒントの行
こういう0とか1とかのことを、マジックナンバーと呼ぶ。

こういうのは定数にするとか、isHead等booleanにするか、意味のない数字を書かないように作るといい。

> i++;
おや、ヒントへ行く前に配列の次要素を使うように指示してるぞ。

>line.substring(0, line.length());
こういう意味のないことをやらないようにしよう。

評価

0

ちょっとわき道失礼します。

>こういう0とか1とかのことを、マジックナンバーと呼ぶ。
0、1の場合、マジックナンバーと呼ばないこともありますよ。
http://ja.wikipedia.org/wiki/%E3%83%9E%E3%82%B8%E3%83%83%E3%82%AF%E3%83%8A%E3%83%B3%E3%83%90%E3%83%BC_%28%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%29

でもflagとして使うなら、私も定数にすることをお勧めしますね。
if (boolean型)だとスマートな気がするんですが、やっぱりちょっと可読性落ちますかね?

評価

0

booleanな考え方を最初に出したのは私なんだけど、若干違和感はあっ
た。
〜か、そうでないか、と割り切れる種類のものだろうか、と。
しっかりと概念を示すなら、列挙になるかなあ。

やっつけなら、さっさとbooleanで終わらせるけどね。

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。