-1

I'm working on a program for my Java class and things were going really well until I inputted a number in the getSideLength method. If the number is valid, it will skip everything back to main and start a new loop on the first quesiton. I honestly have know idea what is going on and neither did my teacher. I'm running of of VS Code if that makes a difference.

package week7;

import java.util.Scanner;
import java.lang.Math;

public class Lab7b {

    static void calculateSideA(){

        double b =  getSideLength("B");
        double c = getSideLength("C");
        double a = Math.sqrt(Math.pow(c,2)-Math.pow(b,2));

        System.out.println("A right triangle with sides 'B' = "+b+" and 'C' (hypotenuse) = "+c+", has a side 'A' which has a length of: "+a);
    }

    static void  calculateSideB(){
        double a =  getSideLength("A");
        double c = getSideLength("C");
        double b = Math.sqrt(Math.pow(c,2)-Math.pow(a,2));

        System.out.println("A right triangle with sides 'A' = "+a+" and 'C' (hypotenuse) = "+c+", has a side 'B' which has a length of: "+b);

    }

    static void  calculateSideC(){
        double a =  getSideLength("A");
        double b = getSideLength("B");
        double c = Math.sqrt(Math.pow(a,2)+Math.pow(b,2));

        System.out.println("A right triangle with sides 'A' = "+a+" and 'B' = "+b+", has a side 'C' (hypotenuse) which has a length of: "+c);

    }





    static double getSideLength(String letter){
        Scanner entry = new Scanner(System.in);
        boolean valid = false;
        double sideLength = 0;
        do{
            try{       
                System.out.print("Please enter the length of the "+letter+" side: ");
                sideLength = entry.nextDouble();
                entry.nextLine();
                valid = true;
            }catch(Exception e){
                System.out.println("Please enter a number.");
                valid = false;
                entry.nextLine();           
            }
        }while(!valid);
        entry.close();
        return sideLength;

    }
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        boolean rerun = false;
        boolean valid = false;
        do{

            String letter = "";

            do{
                try{
                    System.out.print("Enter the side of the triangle would you like to calculate: (A/B/C) ");
                    letter = input.nextLine();
                    if(letter.equalsIgnoreCase("A")||letter.equalsIgnoreCase("B")||letter.equalsIgnoreCase("C")){
                        valid = true;
                        if(letter.equalsIgnoreCase("A")){
                            calculateSideA();
                        }
                        else if(letter.equalsIgnoreCase("B")){
                            calculateSideB();
                        }
                        else if(letter.equalsIgnoreCase("C")){
                            calculateSideC();
                        }
                        else{
                            System.out.println("Something has gone wrong.");
                        }
                    }
                    else{
                        System.out.println("Please enter A, B, or C.");
                        valid = false;
                    }
                }catch(Exception e){
                    System.out.println("Please enter A, B, or C.");
                    valid = false;
                }

            }while(!valid);
            valid = false;


            do{
                System.out.print("Would you like to play again? (Y/N) ");
                String answer = input.nextLine();
            

                if(answer.equalsIgnoreCase("Y")||answer.equalsIgnoreCase("N")){
                    if(answer.equalsIgnoreCase("Y")){
                        valid = true;
                        rerun = true;
                    }
                    else{
                        System.out.println("Thank you. Come Again.");
                        rerun = false;
                        valid = true;
                    }

                }
                else{
                    System.out.println("Please enter either Y or N");
                    valid = false;
                }
            }while(!valid);

        }while(rerun);
        input.close();    
     
    }
    
}

Here's what a run looks like:

Enter the side of the triangle would you like to calculate: (A/B/C) c
Please enter the length of the A side: 5
Enter the side of the triangle would you like to calculate: (A/B/C) Please enter A, B, or C.
Enter the side of the triangle would you like to calculate: (A/B/C) Please enter A, B, or C.
Enter the side of the triangle would you like to calculate: (A/B/C) Please enter A, B, or C.

and on and on.

Any ideas?

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
Ammon
  • 1
  • Where are you going to school and who is your teacher? – hfontanez Oct 24 '22 at 16:55
  • 2
    You have `entry.close()`; in your `getSideLength` method. Remove it. Note the the [`close` method of the `Scanner` API](https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#close()) specifies "If this scanner has not yet been closed [and] if its underlying readable also implements the Closeable interface then the readable's close method will be invoked". So, by closing it, you are also closing your Stdin. – Old Dog Programmer Oct 24 '22 at 17:26
  • @OldDogProgrammer I posted this in my answer. I kind of expanded on that a little and provided the fix for this issue. – hfontanez Oct 24 '22 at 17:28
  • 2
    And in addition, since you're catching `Exception` and discarding its actual cause, you don't see what's going on. – MC Emperor Oct 24 '22 at 17:29

1 Answers1

0

The output

Enter the side of the triangle would you like to calculate: (A/B/C) A
Please enter the length of the B side: 3.0
Please enter the length of the C side: 4.0
A right triangle with sides 'B' = 3.0 and 'C' (hypotenuse) = 4.0, has a side 'A' which has a length of: 2.6457513110645907
Would you like to play again? (Y/N) Please enter either Y or N
Would you like to play again? (Y/N) N
Thank you. Come Again.

The problem:

Once you call close() in your Scanner object, you are closing the input stream. Once you do that, you can't reopen it in the life of the application. You need to work with the same Scanner object throughout. The fact your teacher didn't know that, scares me.

The solution:

Pass the Scanner object to the methods that need to use it.

    static double getSideLength(String letter, Scanner entry) {
        boolean valid = false;
        double sideLength = 0;
        do {
            try {
                System.out.print("Please enter the length of the " + letter + " side: ");
                sideLength = entry.nextDouble();
                valid = true;
            } catch (Exception e) {
                System.out.println("Please enter a number.");
                valid = false;
            }
        } while (!valid);
        return sideLength;
    }

And of course, you need to pass it thru the methods that wraps this one. There might be other (minor) bugs with your application. You will need to clean up those.

hfontanez
  • 5,774
  • 2
  • 25
  • 37