0

I'm trying to read in a text file which looks similar to this:

0000000000 
0000100000
0001001000
0000100000
0000000000

Here is my code:

public static int[][] readBoard(String fileName) throws FileNotFoundException {
    File life = new File(fileName);
    Scanner s = new Scanner(life);

    int row = s.nextInt();
    int columns = s.nextInt();
    int [][] size = new int [row][columns];
    
    for (int i=0; i <= row; i++) {
        String [] state = new String [columns];
        String line = s.nextLine();
        state = line.split("");
        for (int j=0; i <= columns; i++) {
            size[i][j] = Integer.parseInt(state[j]); 
        }
    }
    
    return size;
}

It keeps giving me this error. I think it's the Integer.parseInt(state[j]) that is giving me trouble, but I don't know why.

Exception in thread "main" java.lang.NumberFormatException: For input string: ""
    at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68)
    at java.base/java.lang.Integer.parseInt(Integer.java:662)
    at java.base/java.lang.Integer.parseInt(Integer.java:770)
    at Project5.readBoard(Project5.java:33)
    at Project5.main(Project5.java:9)
John Kugelman
  • 307,513
  • 65
  • 473
  • 519
Cheg18
  • 19
  • 1
  • It says you string is empty. Did you add any System.out.println(...) statements to you code to see: 1) what the value of the "line" variable is and 2) what the value of "state[j]" is? This is basic debugging. – camickr Mar 19 '21 at 00:09
  • You are using the Scanner object in a wrong way to get the column and rows counts. You have to read the file line by line to get the necessary row and column count. Because of that use ArrayList instead of Array, because with ArrayList you can append items dynamically. – xrissz Mar 19 '21 at 00:16

1 Answers1

0

I've executed your code with the example input, and you have logical issues in the code. With the exmaple input the code doesn't even reach the parseInt() line where the asked NumberFormatException could be thwrown. I assume you have tried your code in a different input. The Exception message is staithforward, you tried to parse an empty string to number. It's a typical NumberFormatException. The parseInt() function can throw Exception, so your code must be prepared for it.

The other problem is a basic logical issue in your algorithm. Your row and column variables will be populated with the first to integer token from the text. Based on the exampe input the first integer token will be the first row 0000000000 which integer value is 0, and the second token is 0000100000 which will parsed as 100000. So you are trying to initialize an array with these dimensions which is imposible.

To calculate the row count, you have to read the file line by line. And to get the column counts you have the check the length of the lines. (It can open a new question, how do you want to handle the not properly formatted input file, because in the file the line length can be various.)

That means you can only be sure with the dimensions of the board if you have already iterated though the file content. To prevent the multiple iteration you should use dinamic collection instead of a standard array, like ArrayList.

That means while you are read the file line by line, you can process the the characters one after another in a line. In this step you should be concidered about the invalid characters and the potential empty characters in the end of the file. And during this iteration the final collection can be built.

This example shows a potention solution:

private static int processCharacter(char c) {
    try {
        return Integer.parseInt((Character.toString(c)));
    } catch (NumberFormatException e) {
        return 0;
    }
}

public static List<List<Integer>> readBoard(String fileName) throws FileNotFoundException {
    List<List<Integer>> board = new ArrayList<>();
    File file = new File(fileName);
    FileReader fr = new FileReader(file);

    try (BufferedReader br = new BufferedReader(fr)) {
        String line;
        while ((line = br.readLine()) != null) {
            line = line.trim(); // removes empty character from the line
            List<Integer> lineList = new ArrayList<>();
            if(line.length() > 0) {
                for (int i = 0; i < line.length(); i++) {
                    lineList.add(Main.processCharacter(line.charAt(i)));
                }
                board.add(lineList);
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    return board;
}
xrissz
  • 188
  • 9