0

I'm trying to read a csv file into either an ArrayList or a String [][] array. In this I'm trying to read it into a list and then form the list, using a tokenizer, into an array. The csv file have 7 columns (A - G) and 961 rows (1-961). My for loop for the 2D array keeps returning a null pointer, but I think it should be working..

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();
        }
     }
 }
Raedwald
  • 46,613
  • 43
  • 151
  • 237
Fred V
  • 187
  • 1
  • 11

2 Answers2

3

Initialize your foodArray as foodArray = new String[NUM_ROW][NUM_COL]; before using it.

Also, there is no need for inner for loop as you are reading one row at a time.

use numberOfLines as row:

        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++;
            }

Alternatively, I think you can use split to get all columns as once e.g.

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

One question: Is there any specific purpose for declaring all variables as static class variables? Most of them fit as local variable inside the method e.g. numberOfLines?

Yogendra Singh
  • 33,927
  • 6
  • 63
  • 73
0

You can use this String [][] foodArray = csvreadString(filename); method. It actually reads the file twice, but I don't know how to get the csv dimension without reading the data (you need the dimension in order to initialize the array), and this is very fast in comparison to other methods that I tried.

   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;
    }
Serg
  • 13,470
  • 8
  • 36
  • 47