0

How can I use any alternative to 'goto' in java?

I tried using break label. But since I am not breaking out of any loop, it is giving undefined label error.

import java.io.*;

class $08_02_Total_Avg_Marks
{
    public static void main(String args[]) throws IOException
    {
        //declare and initialize variables
        int subNo = 0, totalMarks = 0;
        float avg = 0.0F;


    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));   
label1:
    System.out.println("Enter no. of subjects");

    //check if input is integer
    try
    {
        subNo = Integer.parseInt(br.readLine().trim());
    }
    catch(NumberFormatException e)
    {
        System.out.println("Please enter a whole number.");
        //goto label1
    }

    int[] marksArray = new int[subNo];

    for(int i=0; i<marksArray.length; i++)
    {label2:
        System.out.println("Enter marks for subject " + (i+1));
        try
        {
            marksArray[i] = Integer.parseInt(br.readLine().trim());
        }
        catch(NumberFormatException e)
        {
            System.out.println("Please enter a whole number.");
            //goto label2
        }
    }

}
}

I was terminating the program on invalid input. But I need to execute the same lines on invalid input.

user3471438
  • 333
  • 1
  • 2
  • 12
  • 1
    `goto` is [not used](https://stackoverflow.com/questions/2545103/is-there-a-goto-statement-in-java) in Java. However, the ability to [break with label](https://stackoverflow.com/questions/886955/how-do-i-break-out-of-nested-loops-in-java?r=SearchResults&s=1|190.0488) is a feature available only in iterative constructs, such as do/while, for, for-each, and while loops. – Avi Aug 06 '19 at 14:04
  • @Avi, you can `break` out of most labeled blocks, not just loops. There are examples here: https://blog.jooq.org/tag/break/ – M. Prokhorov Aug 06 '19 at 14:06
  • Using GoTo labels in object oriented programming? That's virtually the opposite of a good idea... – deHaar Aug 06 '19 at 14:06
  • @deHaar, why? OOP still uses procedures to process events, and there aren't strict rules for breaks inside implementations of said procedures. Only thing I know about `goto` that might be a bad idea is when you go to random place in a different procedure. Also, wouldn't you agree that a method call is also just a fancy `goto`? – M. Prokhorov Aug 06 '19 at 14:12
  • @user3471438, A proper alternative to a `goto` in Java is a method call. You can already tell what to extract into a method, since you already have `label` and `goto label` there. You just need to do that. – M. Prokhorov Aug 06 '19 at 14:14
  • @M.Prokhorov that's exactly why I posted that comment. Use a method call instead (in OOP), even if it is possible and you don't intent to jump to a random place in a different unit of code. – deHaar Aug 06 '19 at 14:14
  • @M.Prokhorov Thanks! It's pretty cool that you can do break in labeled blocks too. – Avi Aug 06 '19 at 14:16
  • just use a loop while the value is not valid – user85421 Aug 06 '19 at 14:29

4 Answers4

4

Rather than wanting to go to a specific point explicitly, wrap the bit you might want to repeat in a loop. If you don't want to execute the loop again, break.

For the first one:

while (true) {
  System.out.println("Enter no. of subjects");

  //check if input is integer
  try
  {
      subNo = Integer.parseInt(br.readLine().trim());
      break;
  }
  catch(NumberFormatException e)
  {
    System.out.println("Please enter a whole number.");
    // Nothing required to continue loop.
  }
}

For the second one, wrap the loop body in loop:

for(int i=0; i<marksArray.length; i++)
{
  while (true) {
    System.out.println("Enter marks for subject " + (i+1));
    try
    {
        marksArray[i] = Integer.parseInt(br.readLine().trim());
        break;
    }
    catch(NumberFormatException e)
    {
        System.out.println("Please enter a whole number.");
    }
  }
}

Or, probably better, write a method wrapping this loop:

int getInt(BufferedReader br) throws IOException {
  while (true) {
    try
    {
      return Integer.parseInt(br.readLine().trim());
    } catch(NumberFormatException e) {
      System.out.println("Please enter a whole number.");
    }
  }
}

and then call this method:

System.out.println("Enter no. of subjects");
int subNo = getInt(br);

for(int i=0; i<marksArray.length; i++) {
    System.out.println("Enter marks for subject " + (i+1));
    marksArray[i] = getInt(br);
}
Andy Turner
  • 137,514
  • 11
  • 162
  • 243
1

This code snippet will loop until a correct number is inserted, in this example (it solves your first goto problem)

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));  
boolean noNumberEntered; //Default on false

System.out.println("Enter no. of subjects");

//TODO: check if input is integer

while(!noNumberEntered){
    try
    {
        subNo = Integer.parseInt(br.readLine().trim());
        noNumberEntered = true;

    }
    catch(NumberFormatException e)
    {
        System.out.println("Please enter a whole number.");
    }
}
Alan
  • 589
  • 5
  • 29
1

I have reformatted your code a little bit. My basic idea was: All of the goto statements can be written in equivalent loops. The first one has now been made with a while loop, which terminates ones there comes NO exception. As for the second label, that has been done with the same mechanism (so a while-loop), however, with a label that can be exited/terminated with a "break + nameOfYourLable" - statement.

import java.io.*;

class $08_02_Total_Avg_Marks
{
public static void main(String args[]) throws IOException
{
    //declare and initialize variables
    int subNo = 0, totalMarks = 0;
    float avg = 0.0F;


BufferedReader br = new BufferedReader(new InputStreamReader(System.in));   
boolean goToLabel1 = true;
while (goToLabel1) {
System.out.println("Enter no. of subjects");

//check if input is integer
try
{
    subNo = Integer.parseInt(br.readLine().trim());
    goToLabel1 = false;  //parsing succeeded, no need to jump to label1
}
catch(NumberFormatException e)
{
    System.out.println("Please enter a whole number.");
    //goto label1
}
}
int[] marksArray = new int[subNo];

for(int i=0; i<marksArray.length; i++)
{
    label2: while (true) {
    System.out.println("Enter marks for subject " + (i+1));
    try
    {
        marksArray[i] = Integer.parseInt(br.readLine().trim());
        break label2;
    }
    catch(NumberFormatException e)
    {
        System.out.println("Please enter a whole number.");
    }
}
}

}
}
0

You can use a do while loop and a boolean instead, like that :

class $08_02_Total_Avg_Marks
{
    public static void main(String args[]) throws IOException
    {
        //declare and initialize variables
        int subNo = 0, totalMarks = 0;
        float avg = 0.0F;


    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));  
    boolean goodEntry = true; 
    do {
        goodEntry = true;
        System.out.println("Enter no. of subjects");

        //check if input is integer
        try
        {
            subNo = Integer.parseInt(br.readLine().trim());
        }
        catch(NumberFormatException e)
        {
            System.out.println("Please enter a whole number.");
            goodEntry = false;
        }
    } while(!goodEntry);
}

You can do the same with your second goto. There are many ways to do that (with while loop and a boolean, with breaks...), but loops are better then goto.

Fifi
  • 467
  • 6
  • 17