0

The while loop should ask the user which option they would like to select, and after the option is complete it should go back to the start of the while loop. Right now, it only works correctly for the second else if, and nothing else.

while(flag){
        System.out.println("Select an option from the menu below:" + 
        "\n1: Display consecutive numbers in a right triangle" + //needs better explanation
        "\n2: Determine if a number is divisible by 3" + 
        "\n3: Determine the number of periods and spaces in a string" +
        "\n4: Display a right triangle of astrisks" + 
        "\n5: Exit"); //better explanation
        String option = input.nextLine();

        if(option.equals("1")){  //does not work
            System.out.println("Enter number of columns: ");
            int width = input.nextInt(); 
            while(width<=0 || width%1!=0){
                System.out.println("Invalid input! Please enter a positive width.");
                width = input.nextInt(); 
            }
            numOfColumns(width);
        }

        else if(option.equals("2")){ //does not work
            System.out.println("Enter number:");
            int num = input.nextInt();
            divisibleBy3(Math.abs(num));
        }

        else if(option.equals("3")){ //works
            System.out.println("Enter string:");
            String sentence = input.nextLine();
            System.out.println("Number of periods and spaces: " + periodsAndSpaces(sentence) + "\n");

        }
        
        else if(option.equals("4")){ //does not work
            System.out.println("Enter the width of the triangle:");
            int length = input.nextInt();
            rightTriangle(length, "");
        }

        else if(option.equals("5")){ //exits the while loop
            flag = false;
        }

        else{
            System.out.println("That is not a valid option!");
        }

    }

For the if/else if statements indicated above, the program will execute the given method, then display the menu, followed by "That is not a valid input!", and then the menu again, even if the user has not entered anything.

cadolphs
  • 9,014
  • 1
  • 24
  • 41
  • 1
    Hi sq_, where are you getting that `input` from? That looks rather like it's reading from a file? And might contain the line-end character `\n`. But right now your code is incomplete. Where does `flag` come from? Can you post a minimum reproducible example? – cadolphs Oct 20 '21 at 03:13
  • Whenever you use `input.nextInt();` you should then consume the rest of the line before calling `input.nextLine();` otherwise, you will likely grab the wrong input unless something else advances the input (for example using `System.out.println(...);`). – sorifiend Oct 20 '21 at 03:29

2 Answers2

0

As mentioned in comments, you need to consume the rest of the line after you use input.nextInt(); or any other method that does not consume the entire line, because it only takes the input of part of the line and the rest remains on the scanner. You can fix this by input.nextLine(); to advance past the current line so that it is ready for the next input when the while loop restarts, like so:

//Get a partial line input eg "nextInt()"
int someInput = input.nextInt();
//Consume the rest of the line
input.nextLine();
//Now process the input
...

Here is a working solution using the above technique:

    if(option.equals("1")){  //does not work
        System.out.println("Enter number of columns: ");
        int width = input.nextInt(); 
        //Consume the rest of the line
        input.nextLine();
        //Now process the input
        while(width<=0 || width%1!=0){
            System.out.println("Invalid input! Please enter a positive width.");
            width = input.nextInt(); 
        }
        numOfColumns(width);
    }

    else if(option.equals("2")){ //does not work
        System.out.println("Enter number:");
        int num = input.nextInt();
        //Consume the rest of the line
        input.nextLine();
        //Now process the input
        divisibleBy3(Math.abs(num));
    }

    else if(option.equals("3")){ //works
        System.out.println("Enter string:");
        String sentence = input.nextLine();
        System.out.println("Number of periods and spaces: " + periodsAndSpaces(sentence) + "\n");

    }
    
    else if(option.equals("4")){ //does not work
        System.out.println("Enter the width of the triangle:");
        int length = input.nextInt();
        //Consume the rest of the line
        input.nextLine();
        //Now process the input
        rightTriangle(length, "");
    }

    else if(option.equals("5")){ //exits the while loop
        flag = false;
    }

    else{
        System.out.println("That is not a valid option!");
    }

This allows each option to work correctly.

sorifiend
  • 5,927
  • 1
  • 28
  • 45
0

I deduce that your input variable is a Scanner object.

Option number 3 is the only one that works as expected because it is the only one that uses nextLine() for the option-specific input, clearing the newline at the end of the input from the input buffer.

If someone selects option 1, and then enters 3, this is what happens:

  1. input contains the string "3\n"
  2. nextInt() reads 3
  3. input still has "\n" in it that hasn't been read yet
  4. numOfColumns(3) runs
  5. The next iteration of the loop starts
  6. It outputs the menu
  7. nextLine() reads from input, immediately finds the \n that's still there from step 3, clears that character, and returns an empty string
  8. option's value of "" falls through to the invalid input case
  9. The loop starts over again
  10. It outputs the menu
  11. nextLine() waits for new input content to be available again

To get the behavior you were expecting, call input.nextLine() after each input.nextInt() call.

Douglas
  • 5,017
  • 1
  • 14
  • 28