-1

I am new in programming. Studying from hyperskills.org. When scanning fill() method, I think program executes an infinite loop. I couldn't understand the debugger module of Intellij IDEA edu.

package machine;
import java.util.Scanner;

public class CoffeeMachine {
    public static Scanner scanner = new Scanner(System.in);

    //Initial Amounts
    private static int waterAmount = 400;
    private static int milkAmount = 540;
    private static int beansAmount = 120;
    private static int disposableCupAmount = 9;
    private static int moneyAmount = 550;

    //Details of Coffee Types: 0 - espresso, 1 - latte, 2 - cappuccino
    private static int coffeeTypeTemp;
    final private static int[][] coffeeDetails = {
            {0, 250, 0, 16, 4},
            {1, 350, 75, 20, 7},
            {2, 200, 100, 12, 6}
    };

    public static void main(String[] args) {
        System.out.println("Write action (buy, fill, take, remaining, exit):");
        String action = scanner.nextLine();

        while (!action.equals("exit")) {
            switch (action) {
                case "buy":
                    buy();
                    System.out.println("Write action (buy, fill, take, remaining, exit):");
                    action = scanner.nextLine();
                    break;
                case "fill":
                    fill();
                    System.out.println("Write action (buy, fill, take, remaining, exit):");
                    action = scanner.nextLine();
                    break;
                case "take":
                    take();
                    System.out.println("Write action (buy, fill, take, remaining, exit):");
                    action = scanner.nextLine();
                    break;
                case "remaining":
                    amountOfGoods();
                    System.out.println("Write action (buy, fill, take, remaining, exit):");
                    action = scanner.nextLine();
                    break;
                default:
                    break;
            }
        }
    }

        public static void buy() {
        System.out.println("What do you want to buy? 1 - espresso, 2 - latte, 3 - cappuccino, back - to main menu:");
        String coffeeType = scanner.nextLine();
        // Initial amount changes according to coffee type
        switch (coffeeType) {
            case "1":
                coffeeTypeTemp = 0;
                isEnoughToMakeCoffee(coffeeTypeTemp);
                break;
            case "2":
                coffeeTypeTemp = 1;
                isEnoughToMakeCoffee(coffeeTypeTemp);
                break;
            case "3":
                coffeeTypeTemp = 2;
                isEnoughToMakeCoffee(coffeeTypeTemp);
                break;
            default:
                break;
        }
    }

    public static void fill() {
        System.out.println("Write how many ml of water do you want to add:");
        int waterFill = scanner.nextInt();
        waterAmount += waterFill;
        System.out.println("Write how many ml of milk do you want to add:");
        int milkFill = scanner.nextInt();
        milkAmount += milkFill;
        System.out.println("Write how many grams of coffee beans do you want to add:");
        int beansFill = scanner.nextInt();
        beansAmount += beansFill;
        System.out.println("Write how many disposable cups of coffee do you want to add:");
        int disposableCupFill = scanner.nextInt();
        disposableCupAmount += disposableCupFill;
    }

    public static void take() {
        System.out.println("I gave you $" + moneyAmount);
        moneyAmount = 0;
    }
    public static void amountOfGoods() {
        System.out.println("The coffee machine has:");
        System.out.println(waterAmount + " of water");
        System.out.println(milkAmount + " of milk");
        System.out.println(beansAmount + " of coffee beans");
        System.out.println(disposableCupAmount + " of disposable cups");
        System.out.println(moneyAmount + " of money");
    }

    public static void isEnoughToMakeCoffee(int coffeeTypeTemp) {
        if ((waterAmount - coffeeDetails[coffeeTypeTemp][1]) < 0) {
            System.out.println("Sorry, not enough water!");
        } else if((milkAmount - coffeeDetails[coffeeTypeTemp][2]) < 0) {
            System.out.println("Sorry, not enough milk!");
        } else if((beansAmount - coffeeDetails[coffeeTypeTemp][3]) < 0) {
            System.out.println("Sorry, not enough coffee beans!");
        } else if((disposableCupAmount) < 0) {
            System.out.println("Sorry, not enough disposable cups!");
        } else {
            System.out.println("I have enough resources, making you a coffee!");
            remaindersOfGoods(coffeeTypeTemp);
        }
    }

    public static void remaindersOfGoods(int coffeeTypeTemp) {
        waterAmount -= coffeeDetails[coffeeTypeTemp][1];
        milkAmount -= coffeeDetails[coffeeTypeTemp][2];
        beansAmount -= coffeeDetails[coffeeTypeTemp][3];
        disposableCupAmount--;
        moneyAmount += coffeeDetails[coffeeTypeTemp][4];
    }

}
Mark Rotteveel
  • 82,132
  • 136
  • 114
  • 158

3 Answers3

0

The problem is, your fill() function reads only integers.

So let's say you have this input:

"fill\n1\n1\n1\n1\nexit"

where \n is newline character.

First, you call nextLine, which is correctly parsed as "fill" and the \n character is read, however it's not part of the output. Then the fill() is called, where you call nextInt() 4x. This function reads characters until it finds any number character, and keeps reading them until it hits any white-space character.

So, at first, it will read 1, because it hits \n.

Then it will read \n1 and it hits \n again. - so you get integer 1.

Then again, it will read \n1 and it hits \n again. This will happen once more, so 1 is read 4x.

Then your function returns back to the while loop, where nextLine() is called.

However, this function will read all character before it hits \n. That means, it will only read \n - so the parsed input is empty, there are no characters before newline, there is no case for this input in your switch, and it's not also equal to exit, so your while loop will actually never end.

To fix it, attach scanner.nextLine() at the end of your fill() function, so the newline character is read before scanning.

Note: The newline character is platform dependent, it may not necessarily be \n.

Ecto
  • 1,065
  • 1
  • 4
  • 12
0

You will have to call the scanner.nextLine() when your fill() method ends, or else it will read a blank space or any such character which was entered while in the fill() method. Also, your default case has just a break, so if the action variable has any value other than what you were expecting, it will go into an infinite loop. So put these lines in the default case too:

System.out.println("Write action (buy, fill, take, remaining, exit):");
action = scanner.nextLine();
0

I think you are getting your issue after using the fill function. This is caused due to using nextInt() not making a new line. You can read more about this at Scanner is skipping nextLine() after using next() or nextFoo()?

Replace your fill function with this.

public static void fill() {
    System.out.println("Write how many ml of water do you want to add:");
    int waterFill = Integer.parseInt(scanner.nextLine());
    waterAmount += waterFill;
    System.out.println("Write how many ml of milk do you want to add:");
    int milkFill = Integer.parseInt(scanner.nextLine());
    milkAmount += milkFill;
    System.out.println("Write how many grams of coffee beans do you want to add:");
    int beansFill = Integer.parseInt(scanner.nextLine());
    beansAmount += beansFill;
    System.out.println("Write how many disposable cups of coffee do you want to add:");
    int disposableCupFill = Integer.parseInt(scanner.nextLine());
    disposableCupAmount += disposableCupFill;
}

Another solution is to simply add a scanner.nextLine() at the end of your function.

RajathaDH
  • 111
  • 2