3

I am working on a practice exercise in my online pursuit to learn Java and am stumped!

The gist of my program is I have the user select an option via the input of a single char, then the program proceeds to cases based off of the value. If the default case executes, that means the input was invalid and I want to then return to the user input prompt.

I initial thought was to use a 'goto', however from what I understand, I would probably be stoned to death by anyone besides me reading the code. And then there's the fact that goto doesn't exist in Java... So while Googling, I found 'labeled breaks'. It looked just like what I needed. However, the spot which I have inserted the label is unrecognized, even though it's in the same class as the cases. How should I go about doing this?

String newLine = System.getProperty("line.separator");

  restart:

  System.out.println("Please select the type of shape you wish to calcuate information for: "
  + newLine + "A: Square" + newLine + "B: Rectangle" + newLine + "C: Circle");

  char typeShape = input.next().charAt(0);

  String shape = Character.toString(typeShape);

  switch (shape.toLowerCase()) {
      case "a": 
          //do something
          break;
      case "b":
          //do something
          break;
      case "c":
          //do something
          break;
      default:
          System.out.println("Invalid selection. Please re-enter shape.");
          break restart;
  }
JVX
  • 95
  • 8

4 Answers4

5

I believe you want to label a block. Something like

restart: {
    System.out.println("Please select the type of shape you wish to calculate "
      + "information for: " + newLine + "A: Square" + newLine + "B: Rectangle"
      + newLine + "C: Circle");

    char typeShape = input.next().charAt(0);

    String shape = Character.toString(typeShape);

    switch (shape.toLowerCase()) {
    case "a": 
        //do something
        break;
    case "b":
        //do something
        break;
    case "c":
        //do something
        break;
    default:
        System.out.println("Invalid selection. Please re-enter shape.");
        break restart;
    }
}
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • 1
    @JVX a better approach will be to use some kind of looping then labels. – YoungHobbit Dec 25 '15 at 06:05
  • Awesome, thanks for the speedy reply! That helps a ton with understanding the labeled breaks. However... when I implemented this and tested it, the program ends after reaching this break instead of looping back up to the label. Why is this happening? – JVX Dec 25 '15 at 06:06
  • @JVX. Yes. You are `break` from the label. Essentially It will come out of the label provided with break statement. – YoungHobbit Dec 25 '15 at 06:08
  • @YoungHobbit Thanks for the reply as well! I saw your example at the bottom. What makes the loop preferable to a label in this instance? I just watched a video on Do-While loops, but I think that I'm going to go back and watch it again. Cheers! – JVX Dec 25 '15 at 06:10
  • @JVX Labeled blocks frowned upon just as much as `goto`. If you want to "go back", you should be using a loop. – Vince Dec 25 '15 at 06:11
  • 1
    @JVX What you are trying to achieve it loop over until correct input is provided. For such purpose you will always use loop. Labels are not made for looping. Sometime when you have multiple loops iterating, and come out of all the loop then use the label, saying from which loop you want to come out (or continue). – YoungHobbit Dec 25 '15 at 06:13
3

Java allows you to label a loop construct (e.g. for, while) and then jump out of the inside one of the loops to an outer level.

The language does not allow you to label arbitrary lines and "goto" them.

UPDATE: Apparently I was wrong. Java supports labeling arbitrary blocks (but not individual statements). See https://stackoverflow.com/a/1940322/14731

Community
  • 1
  • 1
Gili
  • 86,244
  • 97
  • 390
  • 689
3

I guess a simple approach will be to use the do-while loop. If the condition is not satisfied (invalid input/character), continue the loop, otherwise set the flag to false and come out.

boolean inputFlag;
do {
System.out.println("Please select the type of shape you wish to calcuate information for: "
    + newLine + "A: Square" + newLine + "B: Rectangle" + newLine + "C: Circle");

  char typeShape = input.next().charAt(0);
  String shape = Character.toString(typeShape);

  switch (shape.toLowerCase()) {
    case "a":
      inputFlag = false;
      //do something
      break;
    case "b":
      inputFlag = false;
      //do something
      break;
    case "c":
      inputFlag = false;
      //do something
      break;
    default:
      System.out.println("Invalid selection. Please re-enter shape.");
      inputFlag = true;
  }
} while (inputFlag);
YoungHobbit
  • 13,254
  • 9
  • 50
  • 73
2

Labeled blocks are frowned upon for similar reasons goto is frowned upon: it's not a natural flow.

With that said, you might be wondering how you would manage the behavior you want, which is pretty simple: use a loop

//pseudo-code
while(something) {
    repeatCode
}

In your case, you would do something like:

boolean choosing = true;
while(choosing) {
    switch(...) {
        case "a":
            choosing = false;
            break;
        case "b":
            choosing = false;
            break;
    }
}

You may find this a bit verbose. Instead, you could set choosing to false as soon as you enter the loop, then set it back to true if the user didn't enter a correct name.

Or better yet, use a do-while loop:

boolean choosing = false;
do {
    switch(...) {
        case "a":
            break;
        default:
            choosing = true;
            break;
    }
} while(choosing);
Vince
  • 14,470
  • 7
  • 39
  • 84