7

私はプログラミングとクラスの課題に取り組んでいるのが初めてです。今、私は自分のコードを書いてくれる人を求めているわけではありませんが、実行時エラーで立ち往生しています。割り当てでは、ファイルを読み取り、最初の行「15」を使用して配列のサイズを初期化し、各行からの情報で配列を埋める必要があります。

編集:コードが長すぎると思ったので、すべてのコードを投稿したくありませんでしたが、あいまいであるという反対票があったため、ここに行きます.

ファイル:

15
produce,3554,broccoli,5.99,1
produce,3554,broccoli,5.99,1
produce,3555,carrots,2.23,0.25
produce,3555,carrots,2.23,0.25
produce,3555,carrots,2.23,0.25
cleaning,2345,windex,5.99,1 unit
cleaning,2345,windex,5.99,1 unit
cleaning,2345,windex,5.99,1 unit
cleaning,2345,windex,5.99,1 unit
cleaning,2346,toilet paper,12.99,4 rolls
cleaning,2346,toilet paper,12.99,4 rolls
cleaning,2335,windex,2.25,1 mini sprayer
cleaning,1342,wipes,3.99,10 units
cleaning,1342,wipes,3.99,10 units
produce,3546,lettuce,2.99,0.5

私のエラー:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 15
    at Inventory.readFile(Inventory.java:45)
    at Inventory.<init>(Inventory.java:12)
    at Supermarket.main(Supermarket.java:3)

問題の行 45 を含むクラス (行 45 はコメント化されています。右にスクロールします)"

import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;

public class Inventory{
    Product[] list;
    String[] invData;
    private int i = 0;
    public int count;

    public Inventory (String f){
        readFile(f);
    }

    public int indexOfProduct(int code){        
        for(i=0; i<list.length; i++){ 
            if (list[i] != null)
                if (list[i].getCode() == code)
                    return i;

        }
        return -1;
    }


    public Product delete(int pos){
        Product temp = new Product();
        temp = list[pos];
        list[pos] = null;
        return temp;
    }

    public void readFile(String fileName){
        try{
            File invList = new File (fileName);
            Scanner s = new Scanner(invList);
            int itemCount = s.nextInt();
            list = new Product[itemCount];
            count = itemCount;
            while (s.hasNext()){
                String line = s.nextLine();
                invData = line.split(",");
                if (invData[0].equals("produce")){
                    list[i] = new Produce(invData[1], invData[2], invData[3], invData[4]); // This is Line 45, Where the error occurs
                } else if(invData[0].equals("cleaning")){
                    list[i] = new Cleaning(invData[1], invData[2], invData[3], invData[4]);
                }
                i++;
            }//end of while loop
        } catch (FileNotFoundException Abra) {
            String error = Abra.getMessage();
            System.out.println(error);
            } 
    } // end of method

    public Product findCode(int c){
        for(int i=0; i<list.length;i++)
            if(list[1].getCode() == c)
                return list[i];
        return null;
    }//end of method
}//end of class

「ArrayIndexOutOfBoundsException」が発生したのはなぜですか? 二度と繰り返さないように、誰かが私の論理の欠陥を指摘してくれることを願っています。

4

4 に答える 4

6

iそれがその行の唯一の変数インデックスであり、範囲外のインデックスは「15」であり、15項目の配列の終わりを過ぎているため、問題は明らかに の使用にあります。したがって、いくつかの問題があり、すべての使用に関連していますi

nhellwig が述べたように、iこの関数を呼び出す前に、実際に 0 に初期化されていることを確認してください。

さらに、ファイル内のアイテム番号と実際のアイテム数の一貫性に多くの信頼を寄せています。の場合は、警告を生成して配列に項目を格納しようとするのをやめるかi >= itemCount、固定サイズの配列の代わりに、新しい項目を収容するために拡張できる ArrayList のようなコンテナーを使用する必要があります。

i編集: また、アイテムを読んだかどうかに関係なくインクリメントすることを指摘する必要があります。つまり、空白行でもインクリメントiされ、リストまたは配列のオーバーランにギャップが発生します。itemCountアイテムの場合は数字なのでi、実際のアイテムを読んだ場合にのみ増加し、それに固執する必要があります。

同じ精神でinvData.length == 5、ファイル内のカンマなどの位置が間違っていると OOB エラーが発生する可能性があるため、split() を呼び出した後にそれを確認する必要があります。確かに、あなたのプロジェクトでは、「プロデュース」または「クリーニング」で始まる行の要素数について推測することはおそらく問題ありませんが、一般に、ユーザーが作成したファイルからのデータには注意することが重要です。

于 2013-08-06T02:11:38.240 に答える
5

「s.nextLine();」が必要だという答えが見つかりました。

「s.nextInt();」を使ったので ポインターは、ファイルの「15」の最後にぶら下がっていました。次に、While ループの最初の行で「String line = s.nextLine();」リストファイルの2行目で、15の末尾からp inの前に移動したポインタを実行しました。

作業方法は次のようになります。

public void readFile(String fileName){
    try{
        File invList = new File (fileName);
        Scanner s = new Scanner(invList);
        int itemCount = s.nextInt();
        s.nextLine(); // This is the new line that made it work
        list = new Product[itemCount];
        count = itemCount;
        while (s.hasNext()){
            String line = s.nextLine(); //moves file pointer over one
            invData = line.split(",");
            if (invData[0].equals("produce")){
                list[i] = new Produce(invData[1], invData[2], invData[3], invData[4]);
            } else if(invData[0].equals("cleaning")){
                list[i] = new Cleaning(invData[1], invData[2], invData[3], invData[4]);
            }
            i++;
        }//end of while loop
    } catch (FileNotFoundException Abra) {
        String error = Abra.getMessage();
        System.out.println(error);
        } 
} // end of method
于 2013-08-06T15:40:52.120 に答える
3

何回 readFile を呼び出しますか? i = 0;関数の先頭にある必要があります。

于 2013-08-06T02:03:28.600 に答える
3

「i」はグローバル値であってはならず、ゼロに初期化されたメソッド ローカル変数である必要があります。

于 2013-08-06T02:04:41.370 に答える