Infinite Loop when reading Scanner values

Asked

Viewed 106 times

3

My goal is to deposit in several notes (10, 20, 50 and 100). For this, in the method main left so:

static Scanner lerInfo = new Scanner(System.in);

public static void main(String[] args) {

    int nOpc = 0;

    while (nOpc != 9) {
        System.out.println("Opções: ");
        System.out.println("1-Depósito");
        System.out.println("2-Saque");
        System.out.println("3-Extrato");
        System.out.println("9-Sair");
        System.out.println("Qual opção deseja?");
        nOpc = lerInfo.nextInt();

        if (nOpc == 1) {

            Deposito deposito = new Deposito();
            System.out.println("Informe a quantidade de cédulas de CEM para Depósito: ");
            deposito.setQtdCem(lerInfo.nextInt());
            deposito.setTotalCem(lerInfo.nextInt()*100);
            System.out.println("Informe a quantidade de cédulas de CINQUENTA para Depósito: ");
            deposito.setQtdCinq(lerInfo.nextInt());
            deposito.setTotalCinq(lerInfo.nextInt()*50);
            System.out.println("Informe a quantidade de cédulas de VINTE para Depósito: ");
            deposito.setQtdVinte(lerInfo.nextInt());
            deposito.setTotalVinte(lerInfo.nextInt()*20);
            System.out.println("Informe a quantidade de cédulas de DEZ para Depósito: ");
            deposito.setQtdDez(lerInfo.nextInt());
            deposito.setTotalDez(lerInfo.nextInt()*10);
            // deposito.setTotalNoCaixa(deposito.getTotalCem()+deposito.getTotalCinq()+deposito.getTotalVinte()+deposito.getTotalDez());
            // System.out.println(deposito.getTotalNoCaixa());

        }

        if (nOpc == 2) {
            Saque();
        }
        if (nOpc == 3) {
//          ImprimeExtrato();
        }
        if (nOpc == 9) {
            return;
        }

    }

And in class Deposito, left so:

package model;

public class Deposito {

    private int qtdCem;
    private int qtdCinq;
    private int qtdVinte;
    private int qtdDez;

    private int totalCem;
    private int totalCinq;
    private int totalVinte;
    private int totalDez;

    private int totalNoCaixa;

    public int getQtdCem() {
        return qtdCem;
    }

    public void setQtdCem(int qtdCem) {
        this.qtdCem = qtdCem;
    }

    public int getQtdCinq() {
        return qtdCinq;
    }

    public void setQtdCinq(int qtdCinq) {
        this.qtdCinq = qtdCinq;
    }

    public int getQtdVinte() {
        return qtdVinte;
    }

    public void setQtdVinte(int qtdVinte) {
        this.qtdVinte = qtdVinte;
    }

    public int getQtdDez() {
        return qtdDez;
    }

    public void setQtdDez(int qtdDez) {
        this.qtdDez = qtdDez;
    }   

    public int getTotalCem() {
        return totalCem;
    }

    public void setTotalCem(int totalCem) {
        this.totalCem = totalCem;
    }

    public int getTotalCinq() {
        return totalCinq;
    }

    public void setTotalCinq(int totalCinq) {
        this.totalCinq = totalCinq;
    }

    public int getTotalVinte() {
        return totalVinte;
    }

    public void setTotalVinte(int totalVinte) {
        this.totalVinte = totalVinte;
    }

    public int getTotalDez() {
        return totalDez;
    }

    public void setTotalDez(int totalDez) {
        this.totalDez = totalDez;
    }

    public int getTotalNoCaixa() {
        return totalNoCaixa;
    }

    public void setTotalNoCaixa(int totalNoCaixa) {
        this.totalNoCaixa = totalNoCaixa;
    }

}

My problem occurs (checked through debug) when I do the first set:

deposito.setQtdCem(lerInfo.nextInt());

Here the system is stopped, locked, in an infinite loop. Could you please assist me where I’m going wrong? No error message or anything, just stays in the loop.

  • 1

    The function nextInt() should be waiting for an entry (whole, in case). Wouldn’t that be it? The Scanner is waiting for input...

  • Sorry, had not copied this line: Static Scanner lerInfo = new Scanner(System.in); It is just a variable that receives the input.

  • Buddy, Scanner is waiting for an entrance. If you don’t type anything, just stand there. That’s not what you’re seeing?

  • But I’m typing, Leonardo.

  • I added the locking moment: Options: 1-Deposit 2-Loot 3-Extract 9-Quit What option do you want? 1 Enter the amount of CEM banknotes for Deposit: 7 ** And it is locked here.

  • When you type 9, get out of the loop?

  • But in that case, shouldn’t you go to the next println? If I use in the same way, not being called via external class (all within the same class), it will be a beauty.

  • Yes, when I type 9 out of the loop.

  • Where are the implementation of methods: setTotalCem(), setTotalCinq(), setTotalVinte(), setTotalDez() class Deposit?

  • They are all within the same Deposit. I did not add here because the class would be too big. But, I will change to improve.

  • @Victorfreidinger, when typing the desired number your breakpoint is still stopped in the line of the set() method or simply it disappears?

Show 6 more comments

2 answers

3

Change your code and add the entered value to a variable to solve your problem and avoid duplicate call from Scanner sets() that have multiplier, Ex.setTotal(lerInfo.nextInt()*[multiplicador]);

if (nOpc == 1) {
    Deposito deposito = new Deposito();
    System.out.println("Informe a quantidade de cédulas de CEM para Depósito: ");
    nOpc = lerInfo.nextInt();
    deposito.setQtdCem(nOpc);
    deposito.setTotalCem(nOpc * 100);
    System.out.println("Informe a quantidade de cédulas de CINQUENTA para Depósito: ");
    nOpc = lerInfo.nextInt();
    deposito.setQtdCinq(nOpc);
    deposito.setTotalCinq(nOpc * 50);
    System.out.println("Informe a quantidade de cédulas de VINTE para Depósito: ");
    nOpc = lerInfo.nextInt();
    deposito.setQtdVinte(nOpc);
    deposito.setTotalVinte(nOpc * 20);
    System.out.println("Informe a quantidade de cédulas de DEZ para Depósito: ");
    nOpc = lerInfo.nextInt();
    deposito.setQtdDez(nOpc);
    deposito.setTotalDez(nOpc * 10);
    // deposito.setTotalNoCaixa(deposito.getTotalCem()+deposito.getTotalCinq()+deposito.getTotalVinte()+deposito.getTotalDez());
    // System.out.println(deposito.getTotalNoCaixa()); 
}

3


The problem is you’re calling nextInt() twice in a row:

System.out.println("Informe a quantidade de cédulas de CEM para Depósito: ");
deposito.setQtdCem(lerInfo.nextInt());
deposito.setTotalCem(lerInfo.nextInt()*100);

Every call from nextInt() will wait for you to enter some value. Ie:

  1. the program prints the message of the println ("Enter the amount of CEM Deposit notes: ")
  2. the first nextInt() waits for you to enter a number (and passes the entered value to setQtdCem)
  3. the second nextInt() waits for you to type another number (and passes the entered value to setTotalCem).

When it comes to step 3, the program looks like locked/looped, but only because no message was printed saying another number should be typed. But in fact the program is stopped because the nextInt() is waiting for you to type something.

The solution is to do as the André Filipe suggested: keep the value of nextInt() in a variable and use it in both methods (setQtdCem and setTotalCem). This avoids asking for two values:

System.out.println("Informe a quantidade de cédulas de CEM para Depósito: ");
int qtdCem = lerInfo.nextInt();
deposito.setQtdCem(qtdCem);
deposito.setTotalCem(qtdCem * 100);

This is even better, because the value should be the same in the 2 methods, otherwise the class Deposito will be inconsistent. Using two calls from nextInt(), the value typed in each can be different, and then the class Deposito I could have two hundred notes, but with a total of 500, for example.


Speaking of which, there’s no point in two setters, one for the number of notes, and the other for the total value of them. Because the existence of these methods allows you to do things like:

// como criar um Deposito inconsistente
Deposito d = new Deposito();
d.setQtdCem(1); // 1 nota de cem
d.setTotalCem(500000); // total não corresponde com a quantidade de notas
d.setTotalNoCaixa(0); // total não corresponde com as notas existentes

That leaves the class Deposito in an inconsistent state, as totals do not match the number of notes. To avoid this, you could simplify it by eliminating the methods that manipulate totals, as the values of these can be calculated from the amount of notes:

// pode apagar os métodos setTotalXXX e deixar apenas estes:

public int getTotalCem() {
    return this.qtdCem * 100;
}

public int getTotalCinq() {
    return this.qtdCinq * 50;
}

public int getTotalVinte() {
    return this.qtdVinte * 20;
}

public int getTotalDez() {
    return this.qtdDez * 10;
}

public int getTotalNoCaixa() {
    return this.getTotalCem() + this.getTotalCinq() + this.getTotalVinte() + this.getTotalDez();
}

// também pode apagar os campos "totalXXX"

So your code could just call out the methods setQtdXXX:

Deposito deposito = new Deposito();
System.out.println("Informe a quantidade de cédulas de CEM para Depósito: ");
deposito.setQtdCem(lerInfo.nextInt());
System.out.println("Informe a quantidade de cédulas de CINQUENTA para Depósito: ");
deposito.setQtdCinq(lerInfo.nextInt());
System.out.println("Informe a quantidade de cédulas de VINTE para Depósito: ");
deposito.setQtdVinte(lerInfo.nextInt());
System.out.println("Informe a quantidade de cédulas de DEZ para Depósito: ");
deposito.setQtdDez(lerInfo.nextInt());
System.out.println("Total: " + deposito.getTotalNoCaixa());

Totals are calculated from quantities, avoiding that a deposit is inconsistent.

  • Thank you Philip! Just one information, please: If I want to store the total, for example, to use in another deposit, or even to make some calculation in the withdrawal method, how should I proceed? As if it were Total := Total + valueJaExistent. Thank you!

  • @I don’t quite understand your doubt. As it stands, the total deposit is a value that depends exclusively on the amount of each note and I would not change its value directly. If you want to add more notes to a deposit, I suggest creating methods like adicionarNotasDeCem(int quantidade), that adds the number of notes to the current quantity, for example. Vc only deals with the quantities, the total is always calculated accordingly. I don’t know if that’s your question, maybe it’s the case of ask another question.

  • The idea would be, I made a deposit (with the notes of 10, 20, 50 and 100) and I want to make a new deposit (with more values of 10, 20, 50 and 100). I understand that I must keep the values of the first deposit + the value of the second deposit. It would be the case of another question ?

  • 1

    @Victorfreidinger In this case, you can keep a list of deposits, using java.util.List. Each time you create a new deposit, you add the deposit to the list. The way the current code is, you create a deposit within the if and soon after discards it. If you do not know how to work with lists, take a look in this tutorial. If you still have any specific questions, I suggest searching the site, and if not, ask another question.

  • 1

    @Victorfreidinger I’m only suggesting this because the idea of the site is to have specific and focused questions. Even if the doubts are about the same class, this question is about the functioning of the Scanner, and the other question you have looks like be about class model design or how to organize code for a specific purpose (as I understand it, of course). Use lists looks like be the solution, but if you can ask another question by putting more context (what is the purpose of the code - creating deposits is the medium, but what is the ultimate goal?), maybe using lists is not the best solution or

  • 1

    @@hkotsubo, I agree with you. I will work on the suggestions and, if there are more questions, I will return to the forum to detail better. Plus, thanks for the guidelines.

  • 1

    +1. Full reply. He described everything in great detail of what he had thought, however, I didn’t have time to explain it in more detail. Thanks @hkotsubo

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.