javatry-catchjava.util.scanner

How to get the scan.nextLine() without skipping


public void readDrinks(File file) throws DrinkReaderException{
    try {
        Scanner scan = new Scanner(file);
        scan.useDelimiter("::");
        String name,category;
        int price;
        boolean premium;
        while(scan.hasNextLine()) {
            name = "";category = ""; price = -1;
            if(scan.hasNext())
                name = scan.next();
            if(scan.hasNext())
                category = scan.next();
            if(scan.hasNextInt())
                price = scan.nextInt();
            if(scan.hasNextBoolean())
                premium = scan.nextBoolean();
            else
                premium = false;
            System.out.println(name + category + price + premium);
            if(name.isEmpty() || category.isEmpty()) {
                System.out.printf("--Skip the item: %s\n");
                continue;
            }
            if(price == -1 ) {
                System.out.printf("--Incorrect price skip: %s\n");
                continue;
            }
            readerList.add(new Drink(name,category,price,premium));
        }
        scan.close();
    }
    catch(FileNotFoundException e) {
        readFileUI();
    }
}

I'm not sure on how to do it, so that if the file lacks name or category, the program will print something like --Skip the item: Iced Coffe::30. Because, if I were to make a = scan.nextLine() and then put a as %s in name.isEmpty || category.isEmpty it will skip the current line to the next line, which will make scan.next(), scan.nextInt(), and scan.nextBoolean() read the next line.

This is the file with the list of items I need to read.

Name::Category::0::true
Espresso::Hot Coffee::35::false
Chocolate Milk Shake::Cool Drink::60::true 
Hot Plain Milk::Hot Milk::false 
Honey Lemon Iced Tea::Ice Tea::40::false
Double Chocolate Milk Shake::Iced Milk::50::true
Hot Chinese Tea::Hot Tea::30:: false
Iced Caramel Milk::Iced Milk::40
Iced Mocha::Iced Coffee::40::false
Iced Coffee::30
Hot Americano::Hot Coffee::40::false

This is the desired output:

File containing drinks: Drink.txt
Try again! Cannot find the file Drink.txt
File containing drinks: src/Drink.txt
--Incorrect price skip: Hot Plain Milk::Hot Milk::false
--Skip the item: Iced Coffee::30

Solution

  • Instead of using a single Scanner, you could use two of them: one to read the file's lines, and a second one to fetch the data from each line.

    public void readDrinks(File file) throws DrinkReaderException {
        try {
            String line, name, category;
            int price;
            boolean premium;
            Scanner scanParams, scanLines = new Scanner(file);
    
            while (scanLines.hasNextLine()) {
                //added a trim to get rid of eventual spaces
                line = scanLines.nextLine().trim();
    
                scanParams = new Scanner(line);
                scanParams.useDelimiter("::");
    
                name = "";
                category = "";
                price = -1;
    
                if (scanParams.hasNext())
                    name = scanParams.next();
                if (scanParams.hasNext())
                    category = scanParams.next();
                if (scanParams.hasNextInt())
                    price = scanParams.nextInt();
                if (scanParams.hasNextBoolean())
                    premium = scanParams.nextBoolean();
                else
                    premium = false;
    
                System.out.println(name + " - " + category + " - " + price + " - " + premium);
    
                if (name.isEmpty() || category.isEmpty()) {
                    System.out.printf("--Skip the item: %s%n", line);
                    continue;
                }
    
                if (price == -1) {
                    System.out.printf("--Incorrect price skip: %s%n", line);
                    continue;
                }
    
                readerList.add(new Drink(name, category, price, premium));
            }
            scanLines.close();
        } catch (FileNotFoundException e) {
            readFileUI();
        }
    }