0

My goal of this program is to take numbers from an input text file, called seatPrices.txt and save them in an array of type double, called priceArray.

The input file is:

310:300:320:320:300:310
360:350:370:370:350:360
360:350:370:370:350:360
360:350:370:370:350:360
360:350:370:370:350:360
260:250:270:270:250:260
260:250:270:270:250:260
260:250:270:270:250:260
260:250:270:270:250:260
260:250:270:270:250:260
210:200:220:220:200:210
210:200:220:220:200:210
210:200:220:220:200:210
210:200:220:220:200:210
210:200:220:220:200:210
210:200:220:220:200:210
210:200:220:220:200:210
210:200:220:220:200:210
210:200:220:220:200:210
210:200:220:220:200:210
110:100:120:120:100:110
110:100:120:120:100:110
110:100:120:120:100:110
110:100:120:120:100:110
110:100:120:120:100:110
110:100:120:120:100:110
110:100:120:120:100:110
110:100:120:120:100:110
110:100:120:120:100:110
110:100:120:120:100:110

My code for this is:

import java.io.FileReader;
import java.util.Scanner;
import java.io.IOException;

public class testAirline {

    // initializing variables and arrays
    private static final int MAX_COLUMN = 6;
    private static final int MAX_ROW = 30;
    double[][] priceArray;
    FileReader fr;
    Scanner scan;

    // this constructor reserves memory for arrays and sets the filereader and scanner variables, then call "start" method
    public void Airline() throws IOException {      
        priceArray = new double[MAX_ROW][MAX_COLUMN];
        fr = new FileReader(seatPrices);
        scan = new Scanner(fr).useDelimiter(":");
        start();
    }

    // fills the priceArray with numbers from seatPrices.txt
    private void start() {
        for (int i = 0; i < MAX_ROW; i++) {
            for (int j = 0; j <  MAX_COLUMN; j++) {
                priceArray[i][j] = scan.nextDouble();
            }
        }
    }
}

When I run this, I get the following errors in the console:

Exception in thread "main" java.util.InputMismatchException
    at java.util.Scanner.throwFor(Scanner.java:864)
    at java.util.Scanner.next(Scanner.java:1485)
    at java.util.Scanner.nextDouble(Scanner.java:2413)
    at testAirline.start(Airline.java:19)
    at testAirline.Airline(Airline.java:12)

So the errors appear to come from when I call the "start" method (start()) and when the numbers are scanned from the file to be stored in the array. I do not know why these errors are being thrown. Being that I am new to using delimiter, I thought these problems could have stemmed from not formatting it properly, however this suspicious was squashed when I found what lines in my code the errors were being thrown at.

I was not able to find an answer on here that worked in my program. I am open to all possible solutions! Any and all help is appreciated!

Edit:

Output from @robert's suggested code:

:0,0 : 310.0
:0,1 : 300.0
:0,2 : 320.0
:0,3 : 320.0
:0,4 : 300.0
:1,0 : 360.0
:1,1 : 350.0
:1,2 : 370.0
:1,3 : 370.0
:1,4 : 350.0
:2,0 : 360.0
:2,1 : 350.0
:2,2 : 370.0
:2,3 : 370.0
:2,4 : 350.0
:3,0 : 360.0
:3,1 : 350.0
:3,2 : 370.0
:3,3 : 370.0
:3,4 : 350.0
:4,0 : 360.0
:4,1 : 350.0
:4,2 : 370.0
:4,3 : 370.0
:4,4 : 350.0
:5,0 : 260.0
:5,1 : 250.0
:5,2 : 270.0
:5,3 : 270.0
:5,4 : 250.0
:6,0 : 260.0
:6,1 : 250.0
:6,2 : 270.0
:6,3 : 270.0
:6,4 : 250.0
:7,0 : 260.0
:7,1 : 250.0
:7,2 : 270.0
:7,3 : 270.0
:7,4 : 250.0
:8,0 : 260.0
:8,1 : 250.0
:8,2 : 270.0
:8,3 : 270.0
:8,4 : 250.0
:9,0 : 260.0
:9,1 : 250.0
:9,2 : 270.0
:9,3 : 270.0
:9,4 : 250.0
:10,0 : 210.0
:10,1 : 200.0
:10,2 : 220.0
:10,3 : 220.0
:10,4 : 200.0
:11,0 : 210.0
:11,1 : 200.0
:11,2 : 220.0
:11,3 : 220.0
:11,4 : 200.0
:12,0 : 210.0
:12,1 : 200.0
:12,2 : 220.0
:12,3 : 220.0
:12,4 : 200.0
:13,0 : 210.0
:13,1 : 200.0
:13,2 : 220.0
:13,3 : 220.0
:13,4 : 200.0
:14,0 : 210.0
:14,1 : 200.0
:14,2 : 220.0
:14,3 : 220.0
:14,4 : 200.0
:15,0 : 210.0
:15,1 : 200.0
:15,2 : 220.0
:15,3 : 220.0
:15,4 : 200.0
:16,0 : 210.0
:16,1 : 200.0
:16,2 : 220.0
:16,3 : 220.0
:16,4 : 200.0
:17,0 : 210.0
:17,1 : 200.0
:17,2 : 220.0
:17,3 : 220.0
:17,4 : 200.0
:18,0 : 210.0
:18,1 : 200.0
:18,2 : 220.0
:18,3 : 220.0
:18,4 : 200.0
:19,0 : 210.0
:19,1 : 200.0
:19,2 : 220.0
:19,3 : 220.0
:19,4 : 200.0
:20,0 : 110.0
:20,1 : 100.0
:20,2 : 120.0
:20,3 : 120.0
:20,4 : 100.0
:21,0 : 110.0
:21,1 : 100.0
:21,2 : 120.0
:21,3 : 120.0
:21,4 : 100.0
:22,0 : 110.0
:22,1 : 100.0
:22,2 : 120.0
:22,3 : 120.0
:22,4 : 100.0
:23,0 : 110.0
:23,1 : 100.0
:23,2 : 120.0
:23,3 : 120.0
:23,4 : 100.0
:24,0 : 110.0
:24,1 : 100.0
:24,2 : 120.0
:24,3 : 120.0
:24,4 : 100.0
:25,0 : 110.0
:25,1 : 100.0
:25,2 : 120.0
:25,3 : 120.0
:25,4 : 100.0
:26,0 : 110.0
:26,1 : 100.0
:26,2 : 120.0
:26,3 : 120.0
:26,4 : 100.0
:27,0 : 110.0
:27,1 : 100.0
:27,2 : 120.0
:27,3 : 120.0
:27,4 : 100.0
:28,0 : 110.0
:28,1 : 100.0
:28,2 : 120.0
:28,3 : 120.0
:28,4 : 100.0
:29,0 : 110.0
:29,1 : 100.0
:29,2 : 120.0
:29,3 : 120.0
:29,4 : 100.0

3 Answers 3

1

You could assist with your hunt for the flaw by adding some more informative error output e.g.

private void start() {
    for (int i = 0; i < MAX_ROW; i++) {
        for (int j = 0; j <  MAX_COLUMN; j++) {
            try {
                priceArray[i][j] = scan.nextDouble();
            } catch (Exception e) {
                System.err.println("Error discovered at " + i + "," + j ": " + e);
            }
        }
    }
}

This will at least tell you what line/column your input was bad on.

You'll see errors like this:

Error discovered at 0,5: java.util.InputMismatchException

which should indicate to you that the scanner is going beyond the end of the line. You need to guard your call to nextDouble():

                if (scan.hasNextDouble()) {
                    priceArray[i][j] = scan.nextDouble();
                    System.out.println(":" + i + "," + j + " : " + priceArray[i][j]);
                }

You'll also need to advance to the next line for each row:

        if (scan.hasNextLine()) {
            scan.nextLine();
        }

The following revised start() function should correctly parse your input:

// fills the priceArray with numbers from seatPrices.txt
private void start() {
    for (int i = 0; i < MAX_ROW; i++) {
        for (int j = 0; j <  MAX_COLUMN; j++) {
            try {
                if (scan.hasNextDouble()) {
                    priceArray[i][j] = scan.nextDouble();
                    System.out.println(":" + i + "," + j + " : " + priceArray[i][j]);
                }
            } catch (Exception e) {
                System.err.println("Error discovered at " + i + "," + j + ": " + e);
            }
        }
        if (scan.hasNextLine()) {
            scan.nextLine();
        }
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

After implementing this, I noticed that values were being stored in rows 0-29 and columns 0-4. I posted the output in my original question, due to the character limit. I reviewed the values that were printed, and I discovered that the entire sixth column from the input file was left out, and there is no sixth column printing from the array. It did not print any Error discovered at... message. I thought that it was a problem with the for loop for j, however I have it set to run until j<6, so there should be a sixth column. Everything else worked fine. Why would the sixth column be left out?
Update: Changing j < MAX_COLUMN; to j < 7; still leaves out the sixth column. But I did find the problem. Because there is no colon after the numbers in the input file, what I believe is happening is it is being skipped over because the delimiter is set to useDelimiter(":");. After I added colons to the end of each row in the input file, the sixth row was read, stored, and printed properly. Would you be able to explain why this is? Does the Scanner not read the next double if there is no colon after it because of the useDelimiter(":");? Thank you for your help!
Quite frustratingly "A complete token is preceded and followed by input that matches the delimiter pattern" docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#next() - I was able to address this issue by including line separator in the delimiter pattern: useDelimiter("[:\n\r]+") - which isn't ideal but the Scanner API doesn't seem to support an alternative.
Sorry for it being a while for me to respond, but after successfully completing my code with the helpful suggestions from everyone, I did have to use the line separator in the delimiter as useDelimiter(":|\n");.
1

public class InputMismatchException extends NoSuchElementException Thrown by a Scanner to indicate that the token retrieved does not match the pattern for the expected type, or that the token is out of range for the expected type.

priceArray[i][j] = Double.parseDouble(scan.next());

1 Comment

Unfortunately, I got the same errors as before after changing scan.nextDouble to Double.parseDouble(scan.next()). Just out of curiosity, how does scan.next() behave when storing doubles? I was always told in school that scan.next() is reserved for storing Strings.
1

If you check the java docs for the Scanner class, it says that,

The method nextDouble() will throw InputMismatchException if the next token cannot be translated into a valid double value. If the translation is successful, the scanner advances past the input that matched.

Although, in your code you have set the delimiter to :, the code breaks when new line .i.e \n is encountered. Hence, to make your code to store the data in 2D matrix of type double, try changing your scanner to:

Scanner sc = new Scanner(new FileInputStream(new File(pathOfInpFile));

and change your for loops in start() method to:

for(int row = 0; row < rowcount; row++){
                //Read each line. No. of lines will be equal to the no. of rows in file.
                String eachLine = sc.nextLine();
                /*
                 * Split each line at ':'. This gives you a String array of 
                 * length equal to no. of columns in file.
                 */
                String[] columnData = eachLine.split(":");
                for(int col = 0; col < colCount; col++){
                    //Now, store data in your matrix.
                    data[row][col] = Double.parseDouble(columnData[col]);
                }
            }

I hope this solves your problem.

3 Comments

So far, I have not been able to have this work for me. Quick question: what is the advantage of doing Scanner sc = new Scanner(new FileInputStream(new File(pathOfFile)); over doing Scanner sc = new Scanner(fr); ? (where fr is the FileReader variable)
You can do it either way. You can use FileReader or any InputStreamReader. I just wanted to highlight that, it can be done without specifying the delimiter and by reading and splitting each line.
Ah, I was a little confused about it. Thank you for the clarification and the help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.