0

I want to make a loop that repeat requesting for input until the user finally satisfies the condition of a number input instead of a string. By the way I'm using BufferedReader here. Is there a way to repeat it in BigInteger and BufferedReader?

mainLoop: while(true) {
            System.out.println("Choose a number:");
            System.out.println("1 - Addition");
            System.out.println("2 - Subtraction");
            System.out.println("3 - Multiplication");
            System.out.println("4 - Division");
            System.out.println("5 - QUIT");

            try {
                int choice = Integer.parseInt(myObj.readLine());

                BigInteger Num1, Num2, sum, diff, qoutient, product;
                String num1 = null, num2 = null;

                switch (choice) {

                case 1: 

                    try {

                        num1 = myObj.readLine();
                        Num1 = new BigInteger(num1);
                        num2 = myObj.readLine();
                        Num2 = new BigInteger(num2);
                        sum = Num1.add(Num2);

                        System.out.println("The answer is "+sum);


                    } catch (NumberFormatException e){

                    }break;

The output actually returns to the main loop.

  • perhaps loop reading it in as a string, checking if it represents an integer as in https://stackoverflow.com/questions/237159/whats-the-best-way-to-check-if-a-string-represents-an-integer-in-java until it actually does or input is at an end? – Jeremy Kahan May 23 '19 at 05:25
  • Loop it in a string? how to do that? – Peya Calacat May 23 '19 at 06:00
  • You would use an IsInteger() function as defined by the link, set a boolean variable needGoodInput initially to true then do a while(needGoodInput){get your num1 and num2 strings with readline, check IsInteger on each, giving a message if false, if IsInteger is true for both num1 and num2 set needGoodInput false} – Jeremy Kahan May 23 '19 at 11:31
  • Probably to be really clean with this you should define an IsInteger function for the the choice and an IsBigInteger function for the other two numbers. – Jeremy Kahan May 23 '19 at 11:50

2 Answers2

0

UPDATE:

actually I found out the answer. I did a while loop.

subLoop: while (true) {
                    try {

                        System.out.println("Enter 2 numbers");

                        num1 = myObj.readLine();
                        Num1 = new BigInteger(num1);
                        num2 = myObj.readLine();
                        Num2 = new BigInteger(num2);
                        sum = Num1.add(Num2);

                        System.out.println("The answer is "+sum+ "\n");


                    } catch (NumberFormatException e){
                        System.out.println("Use numbers only.");
                        continue subLoop;
                    }
                    break; 
                }
            continue mainLoop;
  • 1
    I suggest you to use `boolean` variable inside your condition and to change the value to exit the loop. Using label is not recommended for every day uses, just some cases where there are needed. Here, there are not needed. – AxelH May 23 '19 at 09:25
0

What AxelH was suggesting is to keep code readable and traceable, you would want to say, for your main loop something like

boolean keepGoing = true;
while (keepGoing){
//main loop stuff here, and in the case where 5 is chosen, set keepGoing = false
}

Note no labels are needed. You may also want to set keepGoing false if your readLine fails (or signals you are at the end of the input).

I would suggest you introduce two simple functions to see if a given string is an integer:

 public boolean isInteger( String input ) {
    try {
        Integer.parseInt( input );
        return true;
    }
    catch( NumberFormatException e ) {
        return false;
    }
}

and

public boolean isBigInteger( String input ) {
    try {
        BigInteger t = new BigInteger( input );
        return true;
    }
    catch( NumberFormatException e ) {
        return false;
    }
}

I am not quite familiar enough with the logic of how your input works, so I don't know if you want to loop until you get a good choice, first, and then worry about the input numbers after. If so, the getting a good choice loop looks like

boolean needAGoodChoice = true;
int choice = 0;
while (needAGoodChoice){
    String numChoice = myObj.ReadLine();
    if (isInteger(numChoice)){
        choice = Integer.parseInt(numChoice);
        //could add check here the number is between 1 and 5 inclusive
        needAGoodChoice=false;
    }
    else{
        System.out.println("Use numbers only for choice.");
    }
}

and when that while concludes, choice has the number of the choice.

The same logic would apply to getting values into your Num1 and Num2 BigIntegers via the num1 and num2 Strings.

boolean needNums = true;
while (needNums){
  System.out.println("Enter 2 numbers");
  num1 = myObj.ReadLine();
  num2 = myObj.ReadLine();
  if (isBigInteger(num1) and isBigInteger(num2)){
      Num1 = new BigInteger(num1);
      Num2 = new BigInteger(num2);
      needNums=false;
      }
      else{
          System.out.println("Use numbers only for operations.");
      }
}

Since all your operations are binary, I think I'd put this getting the numbers loop outside the switch statement (inside an if block that checks choice>=1 and choice<=4) to avoid repeating it 4 times.

Substantively it's not so dramatically different from your solution and looks verbose, but I think in the long run it will be easier to maintain and follow.

Jeremy Kahan
  • 3,796
  • 1
  • 10
  • 23