0

csv ファイルを ArrayList または String [][] 配列に読み込もうとしています。これで、私はそれをリストに読み込んでから、トークナイザーを使用してリストを配列に形成しようとしています。csv ファイルには 7 列 (A ~ G) と 961 行 (1 ~ 961) があります。2D 配列の for ループは null ポインターを返し続けますが、動作するはずだと思います..

public class FoodFacts
{
    private static BufferedReader textIn;
    private static BufferedReader foodFacts;
            static int numberOfLines = 0; 
            static String [][] foodArray;
    public static String  aFact;
    static  int NUM_COL = 7;
    static int NUM_ROW = 961;
    // Make a random number to pull a line
    static Random r = new Random();

    public static void main(String[] args)
    {
        try 
        {
            textIn = new BufferedReader(new InputStreamReader(System.in));
            foodFacts= new BufferedReader(new FileReader("foodfacts.csv"));
            Scanner factFile = new Scanner(foodFacts);
            List<String> facts = new ArrayList<String>();

            String fact;
            System.out.println("Please type in the food you wish to know about.");
            String request = textIn.readLine();
            while ( factFile.hasNextLine()){
                fact = factFile.nextLine();
                StringTokenizer st2 = new StringTokenizer(fact, ",");
                //facts.add(fact);
                numberOfLines++;
                while (st2.hasMoreElements()){
                    for ( int j = 0; j < NUM_COL ; j++) {
                        for (int i = 0; i < NUM_ROW ; i++){
                            foodArray [j][i]= st2.nextToken();  //NULL POINTER HERE
                            System.out.println(foodArray[j][i]);
                        }
                    }
                }
            }
        }
        catch (IOException e)
        {
            System.out.println ("Error, problem reading text file!");
            e.printStackTrace();
        }
     }
 }
4

2 に答える 2

3

foodArrayasを初期化してfoodArray = new String[NUM_ROW][NUM_COL];から使用してください。

また、一度に 1 行ずつ読み取るforため、内部ループは必要ありません。

行として使用numberOfLines:

        while ( factFile.hasNextLine() && numberOfLines < NUM_ROW){
                 fact = input.nextLine();
                 StringTokenizer st2 = new StringTokenizer(fact, ",")    ;
                 //facts.add(fact);
                while (st2.hasMoreElements()){
                  for ( int j = 0; j < NUM_COL ; j++) {
                    foodArray [numberOfLines][j]= st2.nextToken(); 
                    System.out.println(foodArray[numberOfLines][i]);
                 }
                }  
                 numberOfLines++;
            }

splitまたは、すべての列を一度に取得するために使用できると思います。

        while ( factFile.hasNextLine() && numberOfLines < NUM_ROW){
           fact = input.nextLine();
           foodArray [numberOfLines++] = fact.split(",");
        }

1 つの質問:すべての変数を静的クラス変数として宣言する特定の目的はありますか? それらのほとんどは、メソッド内のローカル変数として適合しnumberOfLinesます。

于 2012-11-14T17:44:10.867 に答える
0

このString [][] foodArray = csvreadString(filename);方法を使用できます。実際にはファイルを 2 回読み取りますが、データを読み取らずに csv 次元を取得する方法がわかりません (配列を初期化するには次元が必要です)。これは、私が試した他の方法と比較して非常に高速です。

   static public class PairInt {

        int rows = 0;
        int columns = 0;
    }
   static PairInt getCsvSize(String filename) throws Throwable {
        PairInt csvSize = new PairInt();
        BufferedReader reader = new BufferedReader(new FileReader(new File(filename)));
        String line;
        while ((line = reader.readLine()) != null) {
            if (csvSize.columns == 0) {
                csvSize.columns = line.split(",").length;
            }
            csvSize.rows++;
        }
        reader.close();
        return csvSize;
    }
    static String[][] csvreadString(String filename) throws Throwable {
        PairInt csvSize = getCsvSize(filename);
        String[][] data = new String[csvSize.rows][csvSize.columns];
        BufferedReader reader = new BufferedReader(new FileReader(new File(filename)));
        for (int i = 0; i < csvSize.rows; i++) {
            data[i] = reader.readLine().split(",");
        }
        return data;
    }
于 2012-11-14T17:57:14.107 に答える