I'm trying to make a switch statement that prints out different messages based on whether the user inputs a 1, 2, or 3 but I keep getting errors. Just the small snippet of code below throws about a dozen errors which is probably some sort of record for me. :/
int menuSelection = keyboard.nextint;
switch
case 1: int menuSelection = "1";
break;
case 2: int menuSelection = "2";
break;
case 3: int menuSelection = "3";
break;
The error message is
"case, default, or '>' expected"
but I don't know what that means or how to fix it.
The syntax for your switch statement is incorrect. You need to switch on the variable and also add brackets to enclose your cases:
switch (menuSelection) {
case 1:
break;
case 2:
break;
case 3:
break;
}
Based on the below observations, the switch statement may look like this:
int menuSelection = keyboard.nextint;
String menuSelectionDisplay;
switch(menuSelection)
{
case 1:
menuSelectionDisplay = "1";
break;
case 2:
menuSelectionDisplay = "2";
break;
case 3:
menuSelectionDisplay = "3";
break;
default:
menuSelectionDisplay = "?";
break;
}
Switch statements are required to be surrounded by curly braces {}
It's considered a good idea to have a "default" clause within your switch statement. It acts as a catch-all that gets executed when none of the cases match. In the above example, if the value of menuSelection happened to be 4, the default clause would be executed.
The switch statement takes in one parameter, which is used to determine which case to run. Think of it as a series of if-else statements.
int value = 5;
switch(value)
{
case 5: System.out.println("Hello!"); break;
case 6: System.out.println("Bye!"); break;
default: System.out.println("Huh?"); break;
}
is equivalent to this:
if(value === 5)
{
System.out.println("Hello!");
}
else if(value === 6)
{
System.out.println("Bye!");
}
else
{
System.out.println("Huh?");
}
In your cases, you appear to be setting the value of an int to a String. That's invalid; you would need to either
Set the value of a String to be a String (String s = "1";), or
Set the value of an int to be an int (int i = 1;).
Finally, you cannot re-declare a variable's type multiple times within the code (that's having int menuSelection = keyboard.nextint; and int menuSelection = 3; in the same scope)
int menuSelection = keyboard.nextint;
switch (menuSelection) {
case 1:
menuSelection = "1";
break;
case 2:
menuSelection = "2";
break;
case 3:
menuSelection = "3";
break;
default:
break;
}
Related
I am VERY new to programming...
What can I do to make the switch statement start over when the default case is promted (for example when you enter "5"). Any help would be great!
I saw a similar question about this, but I couldn't use the answers.
int column= StdOut.println();
switch(column) {
case 0: StdOut.println("Good");
break;
case 1: StdOut.println("Ok");
break;
case 2: StdOut.println("Bad");
break;
default:
break;
}
Surround it in a loop and add a variable that breaks the loop when you reach something you like:
int column= StdOut.println();
boolean isBad = true;
do{
switch(column) {
case 0: StdOut.println("Good");
isBad = false;
break;
case 1: StdOut.println("Ok");
isBad = false;
break;
case 2: StdOut.println("Bad");
isBad = false;
break;
default:
isBad = true;
break;
}
}while(isBad);
while(true) {
....
switch (...) {
case ....:
....
break; // Exit switch statement, but not the loop
// More cases here
default:
continue; // Go to the next iteration of the loop
}
break; // Exit the loop
}
I have been working on a utility to parse text files in the format used by Paradox Interactive in their grand strategy games to be used with a visual-based modding tool I am also developing. I have a mostly-implemented, crude, early version of the parser written out and it is mostly working as intended. This is my second attempt at writing a text parser (the first, which ended up working just fine, parsed a subset of XML).
I speed-wrote my parser on the 9th and have spent all weekend trying to debug it, but all my efforts have failed. I have tracked the issue down to the 3rd line of nextChar(). It was throwing an ArrayIndexOutOfBounds error with a crazy small number (in the -2 millions). After I added a bounds check the program just... continues. It reads all the information as needed, it just doesn't ever exit the parse loop.
The format is basically this:
car = {
model_year = 1966
model_name = "Chevy"
components = {
"engine", "frame", "muffler"
}
}
though I have yet to add support for nested lists like I plan, so my test string is:
car = {
model_year = 1966
model_name = "Chevy"
}
For both my understanding and anybody who would see my code, I tried to generously comment my code where I thought it might be necessary, though if any clarification is needed I would be happy to provide it.
My code:
/**
* Parses text files in the format used by Paradox Interactive in their computer games EUIV, CK2, and Stellaris.
*
* #author DJMethaneMan
* #date 12/9/2016
*/
public class Parser
{
private int pos, line, len, depth;
public String text;
private char[] script; //TODO: Initialize in the parse method
public Parser()
{
pos = 0;
line = 1;
len = 0;
depth = 0;
text = "car = {\n" +
" model_year = 1966 \n" +
" model_name = \"Chevy\"\n" +
"}\u0003";
//text = "Hello World";
//Car c = new Car();
//parse(text, c);
}
public static void main()
{
Car c = new Car();
Parser p = new Parser();
p.parse(p.text, c);
System.out.println("The model name is " + c.model_name);
System.out.println("The model year is " + c.model_year);
}
//TODO: Work
public void parse(String text, Parseable parsed)
{
char[] script = text.toCharArray();
this.script = script;
boolean next_char = false;
PARSE_LOOP:while(true)
{
char c;
if(next_char)
{
c = nextChar();
}
else
{
c = script[0];
next_char = true;
}
switch(c)
{
case 'A':
case 'a':
case 'B':
case 'b':
case 'C':
case 'c':
case 'D':
case 'd':
case 'E':
case 'e':
case 'F':
case 'f':
case 'G':
case 'g':
case 'H':
case 'h':
case 'I':
case 'i':
case 'J':
case 'j':
case 'K':
case 'k':
case 'L':
case 'l':
case 'M':
case 'm':
case 'N':
case 'n':
case 'O':
case 'o':
case 'P':
case 'p':
case 'Q':
case 'q':
case 'R':
case 'r':
case 'S':
case 's':
case 'T':
case 't':
case 'U':
case 'u':
case 'V':
case 'v':
case 'W':
case 'w':
case 'X':
case 'x':
case 'Y':
case 'y':
case 'Z':
case 'z':
case '_'://TODO: HERE
if(depth > 0) //
{
parsed.parseRead(buildWordToken(true), this);//Let the class decide how to handle this information. Best solution since I do not know how to implement automatic deserialization.
}
continueUntilChar('=', false); //A value must be assigned because it is basically a key value pair with {} or a string or number as the value
skipWhitespace();//Skip any trailing whitespace straight to the next token.
break;
case '{':
depth++;
break;
case '}':
depth--;
break;
case '\n':
line++;
break;
case ' ':
case '\t':
skipWhitespace();
break;
case '\u0003': //End of Text Character... Not sure if it will work in a file...
break PARSE_LOOP;
}
}
}
//Returns a string from the next valid token
public String parseString()
{
String retval = "";
continueUntilChar('=', false);
continueUntilChar('"', false);
retval = buildWordToken(false);
continueUntilChar('"', false); //Don't rewind because we want to skip over the quotation and not append it.
return retval;
}
//Returns a double from the next valid token
public double parseNumber()
{
double retval = 0;
continueUntilChar('=', false); //False because we don't want to include the = in any parsing...
skipWhitespace(); //In case we encounter whitespace.
try
{
retval = Double.parseDouble(buildNumberToken(false));
}
catch(Exception e)
{
System.out.println("A token at line " + line + " is not a valid number but is being passed as such.");
}
return retval;
}
/**********************************Utility Methods for Parsing****************************************/
protected void continueUntilChar(char target, boolean rewind)
{
while(true)
{
char c = nextChar();
if(c == target)
{
break;
}
}
if(rewind)
{
pos--;
}
}
protected void skipWhitespace()
{
while(true)
{
char c = nextChar();
if(!Character.isWhitespace(c))
{
break;
}
}
pos--;//Rewind because by default parse increments pos by 1 one when fetching nextChar each iteration.
}
protected String buildNumberToken(boolean rewind)
{
StringBuilder token = new StringBuilder();
String retval = "INVALID_NUMBER";
char token_start = script[pos];
System.out.println(token_start + " is a valid char for a word token."); //Print it.
token.append(token_start);
while(true)
{
char c = nextChar();
if(Character.isDigit(c) || (c == '.' && (Character.isDigit(peek(1)) || Character.isDigit(rewind(1))))) //Makes sure things like 1... and ...1234 don't get parsed as numbers.
{
token.append(c);
System.out.println(c + " is a valid char for a word token."); //Print it for debugging
}
else
{
break;
}
}
return retval;
}
protected String buildWordToken(boolean rewind)
{
StringBuilder token = new StringBuilder(); //Used to build the token
char token_start = script[pos]; //The char the parser first found would make this a valid token
token.append(token_start); //Add said char since it is part of the token
System.out.println(token_start + " is a valid char for a word token."); //Print it.
while(true)
{
char c = nextChar();
if(Character.isAlphabetic(c) || Character.isDigit(c) || c == '_')//Make sure it is a valid token for a word
{
System.out.println(c + " is a valid char for a word token."); //Print it for debugging
token.append(c); //Add it to the token since its valid
}
else
{
if(rewind)//If leaving the method will make this skip over a valid token set this to true.
{
//Rewind by 1 because the main loop in parse() will still check pos++ and we want to check the pos of the next char after the end of the token.
pos--;
break; //Leave the loop and return the token.
}
else //Otherwise
{
break; //Just leave the loop and return the token.
}
}
}
return token.toString(); //Get the string value of the token and return it.
}
//Returns the next char in the script by amount but does not increment pos.
protected char peek(int amount)
{
int lookahead = pos + amount; //pos + 1;
char retval = '\u0003'; //End of text character
if(lookahead < script.length)//Make sure lookahead is in bounds.
{
retval = script[lookahead]; //Return the char at the lookahead.
}
return retval; //Return it.
}
//Returns the previous char in the script by amount but does not decrement pos.
//Basically see peek only this is the exact opposite.
protected char rewind(int amount)
{
int lookbehind = pos - amount; //pos + 1;
char retval = '\u0003';
if(lookbehind > 0)
{
retval = script[lookbehind];
}
return retval;
}
//Returns the next character in the script.
protected char nextChar()
{
char retval = '\u0003';
pos++;
if(pos < script.length && !(pos < 0))
{
retval = script[pos]; //It says this is causing an ArrayIndexOutOfBoundsException with the following message. Shows a very large (small?) negative number.
}
return retval;
}
}
//TODO: Extend
interface Parseable
{
public void parseRead(String token, Parser p);
public void parseWrite(ParseWriter writer);
}
//TODO: Work on
class ParseWriter
{
}
class Car implements Parseable
{
public String model_name;
public int model_year;
#Override
public void parseRead(String token, Parser p)
{
if(token.equals("model_year"))
{
model_year = (int)p.parseNumber();
}
else if(token.equals("model_name"))
{
model_name = p.parseString();
}
}
#Override
public void parseWrite(ParseWriter writer)
{
//TODO: Implement along with the ParseWriter
}
}
Use of the labeled break statement break PARSE_LOOP; is generally considered bad practice. You are essentially writing a "goto" statement: whenever the break PARSE_LOOP; condition is hit, it jumps back to the beginning of the while loop (because that's where you wrote PARSE_LOOP:). This is probably the reason for your infinite loop. I also don't understand why you would restart a while loop that is already infinite (while true).
Change your code to:
public void parse(String text, Parseable parsed)
{
char[] script = text.toCharArray();
this.script = script;
boolean next_char = false;
boolean parsing = true;
while(parsing)
{
char c;
if(next_char)
{
c = nextChar();
}
else
{
c = script[0];
next_char = true;
}
switch(c)
{
case 'A':
case 'a':
case 'B':
case 'b':
case 'C':
case 'c':
case 'D':
case 'd':
case 'E':
case 'e':
case 'F':
case 'f':
case 'G':
case 'g':
case 'H':
case 'h':
case 'I':
case 'i':
case 'J':
case 'j':
case 'K':
case 'k':
case 'L':
case 'l':
case 'M':
case 'm':
case 'N':
case 'n':
case 'O':
case 'o':
case 'P':
case 'p':
case 'Q':
case 'q':
case 'R':
case 'r':
case 'S':
case 's':
case 'T':
case 't':
case 'U':
case 'u':
case 'V':
case 'v':
case 'W':
case 'w':
case 'X':
case 'x':
case 'Y':
case 'y':
case 'Z':
case 'z':
case '_'://TODO: HERE
if(depth > 0) //
{
parsed.parseRead(buildWordToken(true), this);//Let the class decide how to handle this information. Best solution since I do not know how to implement automatic deserialization.
}
continueUntilChar('=', false); //A value must be assigned because it is basically a key value pair with {} or a string or number as the value
skipWhitespace();//Skip any trailing whitespace straight to the next token.
break;
case '{':
depth++;
break;
case '}':
depth--;
break;
case '\n':
line++;
break;
case ' ':
case '\t':
skipWhitespace();
break;
case '\u0003': //End of Text Character... Not sure if it will work in a file...
parsing = false;
break;
}
}
}
Put a debug statement in to prove that it's hitting your break, I'm guessing it's not (Although it could be the break label--I haven't had reason to look into that construct since I first learned java a couple decades ago). I have a couple suggestions though...
I'd use isAlpha instead of that part of the switch. Cleaner, shorter, probably about as efficient and language-agnostic.
Instead of using the break label (Which is very uncommon), You might want to use boolean parsing=true;while(parsing)... instead. It's not really wrong to use the break label, but... Anything that causes the next guy to spend a minute or two scratching his head is a few minutes wasted.
here i tried to get output month by inputting month number but why i am having error
- "monthString" mightn't have been initialized ?
- and why i am not getting output string from " monthString "?
why monthString have to be initialized ?
import java.util.Scanner;
public class SwitchClass {
public static void main(String[]args)
{
Scanner input = new Scanner(System.in);
System.out.printf(" when did u born ? ");
int monthNumber = input.nextInt();
String monthString ;
switch (monthNumber)
{
case 1:
monthString = "January ";
break;
case 2:
monthString = "February ";
break;
case 3:
monthString = "March ";
break;
case 4:
monthString = "April ";
break;
case 5:
monthString = "May";
break;
case 6:
monthString = "June";
break;
case 7:
monthString = "July";
break;
case 8:
monthString = "August";
break;
case 9:
monthString = "September";
break;
case 10:
monthString = "October";
break;
case 11:
monthString = "November";
break;
case 12:
monthString = "December";
break;
}
System.out.println(monthString); }
}
What if monthNumber is not between 1 and 12? In that case, monthString won't be initialized. You should give it some default value when you declare it :
String monthString = null; // or ""
It would be a good idea to add a default case to your switch statement.
Example:
switch (monthNumber) {
case 1: monthString = "January";
break;
//other cases...
default: monthString = "Invalid Month Number";
break;
}
This way if monthNumber is not 1-12 then there is still a default case for the switch statement to flow to.
May be this link will help to get proper understanding.
http://stackoverflow.com/questions/5478996/should-java-string-method-local-variables-be-initialized-to-null-or
monthString is a local variable within main(), therefore, it must be initialized to prevent the compiler error.
If monthString were a Class variable then it does not have to be initialized explicitly.
You can do this by moving monthString outside of main() and declare it as:
static String monthString;
Because the designer of Java language believes it made more sense for it to be! Codes are easier to read when variables are initialised. A statement String foo; feels non-deterministic because you have to guess what's the default value of String is whereas String foo = null; is more deterministic.
To give you a more obvious example, consider this:
int x;
Int y;
Can you very quickly guess what the default values are? You probably have to pause for a few second to realize x is probably 0 and y is probably null
Local variables MUST always be initialized before use.
For Java 6, the compiler doesn't consider the "Incomplete" initialization of variables within flow control blocks and try-catch blocks. The initialization must be done for all cases:
If - else:
String s;
int a = 10;
if(a > 5){
s = "5";
}else{
System.out.println("");
}
System.out.println(s); // error if s isn't initialized within both if and else blocks
While loop:
String s;
int a = 10;
while(a > 0) {
s= ">0";
a--;
}
System.out.println(s);// error if s isn't initialized outside the while
Try-Catch block:
String s;
try {
s = "";
} catch (Exception e) {}
System.out.println(s);// error if s isn't initialized within both try and catch blocks
Switch block:
String s;
int a = 10;
switch (a) {
case 10:
s="10";
break;
default:
break;
}
System.out.println(s);// error if s isn't initialized all cases, default case included
Initialize the variable before the switch and all will be fine.
String monthString = "";
Please read the following function:
public static int getValue(int i) {
int result = 0;
switch (i) {
case 1:
result = result + i;
case 2:
result = result + i * 2;
case 3:
result = result + i * 3;
}
return result;
}
When i = 2, what is the output? I think it is 4, but the answer is 10 by execution. Why does this happen? Why does case 3 also execute? i is 2, not 3. I'm trying to think about it but I still don't know why this happens.
Switch statements require break; for each case to avoid executing later case statements.
Use break to avoid next case execution.
public static int getValue(int i) {
int result = 0;
switch (i) {
case 1:
result = result + i;
break;
case 2:
result = result + i * 2;
break;
case 3:
result = result + i * 3;
break;
}
default:
break;
return result;
}
You are forgetting to `break; the switch statement.
It should look something like this when you are done:
case 1:
//code
break;
case 2:
//code
break;
Also it's always good to include a defualt case:
default:
System.err.println("Something went terribly wrong!");
Sorry if this has been posted before, this should fix everything.
I also have a reason as to why whats happening is happening:
result is being saved from case 1, and reused with the new value. This is getting that funky error of yours.
The case statement needs a break statement to stop it going into the next case statement.
Also good to have a default case
switch (i) {
case 1:
result = result + i;
break;
case 2:
result = result + i * 2;
break;
case 3:
result = result + i * 3;
break;
default:
log.error (...);
}
Use "break;" to prevent the code from running into the next case automatically.
switch (choice)
{
case 0:
//codes
break;
case 1:
//codes
break;
case 2:
//codes
break;
case 3:
//codes
break;
}
Here I have some problem when I use while loop in switch statement using dialog boxes. Some statements are unreachable and dialog boxes not appeared. Please help me! And also can do some correction on my code.
This the simple code that I made:
public static void main(String[] args)
{
// prompt and read first number from user
String no = JOptionPane.showInputDialog(null, "Enter the number");
int num = Integer.parseInt(no); //convert string to number
switch (num)
{
//display result
default: JOptionPane.showMessageDialog(null,"fail"); break;
case 1: JOptionPane.showMessageDialog(null,"c=a+b"); break;
case 2: JOptionPane.showMessageDialog(null,"c=a/b"); break;
case 3: JOptionPane.showMessageDialog(null,"c=a*b"); break;
case 4: JOptionPane.showMessageDialog(null,"c=a-b"); break;
}
}
The cases in a switch/case are evaluated in the order you put them. default matches all cases. Since you have that first and that case does something before breaking out of it, the other cases will never be reached. Try this instead:
case 1: JOptionPane.showMessageDialog(null,"c=a+b"); break;
case 2: JOptionPane.showMessageDialog(null,"c=a/b"); break;
case 3: JOptionPane.showMessageDialog(null,"c=a*b"); break;
case 4: JOptionPane.showMessageDialog(null,"c=a-b"); break;
default: JOptionPane.showMessageDialog(null,"fail"); break;
Your code does not show a while loop anywhere. Perhaps you can update with the code you attempted.
switch (num)
{
case 1:
while(!your condition)
{
JOptionPane.showMessageDialog(null,"c=a+b");
}
break;
case 2: JOptionPane.showMessageDialog(null,"c=a/b"); break;
case 3: JOptionPane.showMessageDialog(null,"c=a*b"); break;
case 4: JOptionPane.showMessageDialog(null,"c=a-b"); break;
default: JOptionPane.showMessageDialog(null,"fail"); break;
}
Retype the code:
// prompt and read first number from user
String no = JOptionPane.showInputDialog(null, "Enter the number");
int num = Integer.parseInt(no); //convert string to number
while (num<=4)
{
if
switch (num)
{
//display result
case 1: JOptionPane.showMessageDialog(null,"c=a+b"); break;
case 2: JOptionPane.showMessageDialog(null,"c=a/b"); break;
case 3: JOptionPane.showMessageDialog(null,"c=a*b"); break;
case 4: JOptionPane.showMessageDialog(null,"c=a-b"); break;
default: JOptionPane.showMessageDialog(null,"fail"); continue;
}
}// end method main
}// end class abc