Alexandru Cimpanu
Alexandru Cimpanu

Reputation: 1069

Java Scanner does not get all the lines

I have the following method that gets the input from text and then it should store it line by line:

public static MDVRPData parse(String myFile) {
    MDVRPData myData = new MDVRPData(0, 0, 0, null, null);
    try {
        Scanner s = new Scanner(new FileReader(myFile));
        int currentLine = 1;
        String line = s.nextLine();
        String delims = "[ ]+";
        String[] tokens = line.split(delims);
        if (Integer.parseInt(tokens[0]) != 2) {
            System.out.println("The data might not be appropriate.");
        }
        myData.setNrVehicle(Integer.parseInt(tokens[1]));
        myData.setNrCustomers(Integer.parseInt(tokens[2]));
        myData.setNrDepots(Integer.parseInt(tokens[3]));
        DepotData[] dData = new DepotData[myData.getNrDepots()];
        CustomerData[] cData = new CustomerData[myData.getNrCustomers()];
        while (s.hasNextLine()) {
            line = s.nextLine();
            delims = "[ ]+";
            tokens = line.split(delims);
            currentLine++;
            for (int i = 0; i < tokens.length; i++) {
                System.out.print(tokens[i] + ' ');
            }
            System.out.println(currentLine);
            if (currentLine <= myData.getNrDepots() + 1) {
                dData[currentLine - 2].setMaxDuration(Integer.parseInt(tokens[0]));
                dData[currentLine - 2].setMaxLoad(Integer.parseInt(tokens[1]));
            }

            if ((currentLine > myData.getNrDepots() + 1) && (currentLine <= 1 + myData.getNrDepots() + myData.getNrCustomers())) {
                cData[currentLine - 1 - myData.getNrDepots()].setNumber(Integer.parseInt(tokens[0]));
                cData[currentLine - 1 - myData.getNrDepots()].setxCoord(Integer.parseInt(tokens[1]));
                cData[currentLine - 1 - myData.getNrDepots()].setyCoord(Integer.parseInt(tokens[2]));
                cData[currentLine - 1 - myData.getNrDepots()].setServiceDuration(Integer.parseInt(tokens[3]));
                cData[currentLine - 1 - myData.getNrDepots()].setDemand(Integer.parseInt(tokens[4]));
                cData[currentLine - 1 - myData.getNrDepots()].setFrequencyOfVisit(Integer.parseInt(tokens[5]));
                cData[currentLine - 1 - myData.getNrDepots()].setVisitCombNr(Integer.parseInt(tokens[6]));
                int j;
                int[] temp = new int[Integer.parseInt(tokens[6])];
                for (j = 0; j < temp.length; j++) {
                    temp[j] = Integer.parseInt(tokens[7 + j]);
                }
                cData[currentLine - 1 - myData.getNrDepots()].setVisitCombList(temp);
            }
            if (currentLine > myData.getNrCustomers() + myData.getNrDepots() + 1) {
                dData[currentLine - myData.getNrCustomers() + myData.getNrDepots() + 2].setNumber(Integer.parseInt(tokens[0]));
                dData[currentLine - myData.getNrCustomers() + myData.getNrDepots() + 2].setxCoord(Integer.parseInt(tokens[1]));
                dData[currentLine - myData.getNrCustomers() + myData.getNrDepots() + 2].setyCoord(Integer.parseInt(tokens[2]));
            }
        }
        myData.setCustomerData(cData);
        myData.setDepotData(dData);

    } catch (IOException ex) {
        ex.printStackTrace(); // for now, simply output it.
    } finally {
        return myData;
    }
}

This is a part of the input text:

2 2 50 4
0 160
0 160
0 160
0 160
1 37 52 0   7 1 4 1 2 4 8
2 49 49 0  30 1 4 1 2 4 8
3 52 64 0  16 1 4 1 2 4 8
4 20 26 0   9 1 4 1 2 4 8
5 40 30 0  21 1 4 1 2 4 8
6 21 47 0  15 1 4 1 2 4 8

For some reason the code reads the first line correct, goes into the while loop, reads the second line correct and it stops. Before implementing this method I wrote one that simply got the file line by line and then split it String line = s.nextLine(); String delims ="[ ]+"; String[] tokens = line.split(delims) and print it and it worked without a problem.

Upvotes: 0

Views: 181

Answers (2)

Sean Landsman
Sean Landsman

Reputation: 7179

Is it possible that your code is throwing a non-IOException? If it does, then your application will silently swallow the error and return the lines read so far.

For example, in the following contrived code snippet even though a RuntimeException is thrown, it will simply be ignored:

    try {
        int i = 0;
        if (i == 1) {
            throw new IOException("wont be thrown");
        }
        throw new RuntimeException("boom");
    } catch(IOException e) {
        System.out.println("Got an exception");
    } finally {
        return "a result";
    }

"a result" will be returned and the calling code will be none the wiser.

To check, I suggest adding a "catch all" block to verify:

    ...
    } catch(IOException e) {
        System.out.println("Got an exception");
    } catch(Throwable te) {
        System.out.println("Got another exception");
    } finally {
    ...

Upvotes: 1

Alexandru Cimpanu
Alexandru Cimpanu

Reputation: 1069

I managed to find my mistake with help from Sean Landsman. I added a further catch after the IOException:

    } catch (Throwable e) {
        System.out.println("Got another exception");
        final StringWriter sw = new StringWriter();
        final PrintWriter pw = new PrintWriter(sw, true);
        e.printStackTrace(pw);
        System.out.println(sw.getBuffer().toString());
    }

I got NullPointerException because I was not initializing my objects after creating the arrays. I got rid of the error by adding the following code:

        DepotData[] dData = new DepotData[myData.getNrDepots()];
        for (int i = 0; i < myData.getNrDepots(); i++) {
            dData[i] = new DepotData(0, 0, 0, 0, 0);
        }
        CustomerData[] cData = new CustomerData[myData.getNrCustomers()];
        for (int i = 0; i < myData.getNrCustomers(); i++) {
            cData[i]= new CustomerData(0, 0,0,0,0,0,0,null);
        }

Upvotes: 1

Related Questions