I'm trying to use string input (yes or no) as a sentinel for a loop. The loop repeats a switch statement, and at the end prompts the user with a yes or no question. Until they type 'yes' as their answer, the loop continues to receive data from the user. The problem comes from trying to receive a new value for the sentinel.
***Reviewed the comments and made some changes. Here's the updated code:
Scanner input = new Scanner ( System.in );
System.out.print( "Please enter a product number, 1 - 5: ");
int product = input.nextInt();
double sum = 0;
boolean complete = false;
while (!complete) {
switch (product){
case 1: sum = sum + 2.98;
break;
case 2: sum = sum + 4.50;
break;
case 3: sum = sum + 9.98;
break;
case 4: sum = sum + 4.49;
break;
case 5: sum = sum + 6.87;
break;
}
System.out.print( "Is your order complete? Please type true or false:");
complete = in.nextLine();
}
All of that is working but I am still having trouble with the prompt to break the sentinel. I'm trying to get it set up to where the user types true to end the loop or false to continue it. I'm starting to think I've overlooked something. I greatly appreciate the help, thank you.
Change
default: String complete = input.Stream(); //Not coded, but will also ask for input.
to
default: complete = input.Stream(); //Not coded, but will also ask for input.
You're redeclaring a String, which is not what you want. And follow the advice given of using .equals, not == for Strings or other reference types.
It's griping because you declared it twice. Take off the second String declaration:
default: complete = input.Stream(); //Not coded, but will also ask for input.
You are declaring complete twice. Try modifying your default case statement as:
default: complete = input.Stream()
Two things:
1) you are redeclaring complete. The default case should just be:
default: complete = input.Stream();
2) in Java you can't compare Strings with !=. Every String is an object and by using the comparison operators you are comparing the identifiers of the objects, not the contents of the objects. Java will never see two String objects as equal unless they are two strings pointing to the same memory location. To compare the values of two strings you have to use the .equals() method such as:
while (!complete.equals("yes")) {
Or even better as a habit:
while (!"yes".equals(complete)) {
This is better because if the complete String variable were null then the first comparison would throw a null pointer exception where the second won't since the literal string "yes" will always evaluate to a not-null object.
Hope that helps.
David
Related
The code below is for a simple calculator with the four basic mathematical operators. It is a working program, it works as expected. However, I have a few questions to understand and improve both my program as well as my understanding of Java. (I have used google but the amount of redundant info confuses me and haven't found any perfect answers on StackOverflow too, though there are dozens of related questions. Believe me, I did tried before posting here).
How can I make sure that the user input is exactly and strictly one char?
here in my program, it accepts more than one character (+-*) but operates on the first char (+) only. I want to make sure more than one character is not accepted as input.
After successful execution of the program, how can I somehow let the user repeat the main method? I mean, a user adds two numbers, gets his answer and he wants to do another calculation, maybe multiply two numbers this time. I can ask the user for yes or no to continue but how do I take him/her back to the beginning? (will a loop work? how?)
A the end of the program I used two methods to output a message. The system.out.print works fine but the JOptionPane method doesn't display the message and the program doesn't terminate (I have commented it out). I would like to understand why?
Is the default case required in the switch? And Am I following the correct code structure? (the arrangements and uses of curly braces)
NB: As I said this calculator works fine and can be used by newbies like myself to better understand the concept as I have commented on every detail. Please understand that I couldn't add everything in the question title due to limits...
package mycalculator;
import javax.swing.JOptionPane;
import java.util.*;
public class MyCalculator{
public static void main (String [] args){
// Let us code a simple calculator//
// Variable type declarations//
char OP;
int firstNum;
int secNum;
// Display an explanation of what this program does//
System.out.println("This is a simple calculator that will do basic
calculations such as :"
+ "\nAddition, Multiplication, Substraction and Division.");
// Create a scanner object to Read user Input.//
Scanner input = new Scanner(System.in);
// Ask user to input any positive number and read it//
System.out.println("Enter Any positive number followed by pressing
ENTER.");
firstNum = input.nextInt();
// Ask user to input/decide his choice operator and read it //
System.out.println("Enter a valid OPERATOR sign followed by pressing
ENTER.");
OP = input.next().charAt(0);
// Loop the below statement till one of the four (+,-,*,/) is entered.//
while(OP != '+' && OP != '-' && OP != '*' && OP != '/'){
System.out.println("Please Re-enter a valid Operator (+,-*,/)");
OP = input.next().charAt(0);}
// Ask user for any second number and read it//
System.out.println("Enter your Second number followed by an ENTER
stroke.");
secNum = input.nextInt();
// Various possible Resolution based on OP value.//
int RSum = firstNum+secNum;
int RSubs= firstNum-secNum;
int RPro = firstNum*secNum;
double DPro = firstNum/secNum;
// Conditional statements for Processing Results based on OP and display.//
switch(OP){
case '+': System.out.println("The Resulting sum is "+ RSum);
break;
case '-': System.out.println("The Resulting sum is "+ RSubs);
break;
case '*': System.out.println("The Resulting Product is "+ RPro);
break;
case '/': System.out.println("The Resulting Divisional product is "+
DPro);
break;
//Maybe the default case is actually not needed but is added for totality//
default : System.out.println("Try Again");
break;
}
// The following code maybe deleted, it is for experimental purpose//
// Just checking if additional statements executes after a program
completes//
System.out.println("Test Message ");
// JOptionPane.showMessageDialog(null, "The Process Ends Here!");
//The test message works fine//
//The JOptionPane statement don't work and program doesn't end. WHY?//
}
}
How can I make sure that the user input is exactly and strictly one
char? here in my program, it accepts more than one character (+-*) but
operates on the first char (+) only. I want to make sure more than one
character is not accepted as input.
If you use console application and Scanner, only thing that you can do is read a String and check its length. In case you use Swing, you could implement KeyPressListener and proceed exactly after user press a button (but not for console application).
After successful execution of the program, how can I somehow let the
user repeat the main method? I mean, a user adds two numbers, gets his
answer and he wants to do another calculation, maybe multiply two
numbers this time. I can ask the user for yes or no to continue but
how do I take him/her back to the beginning? (will a loop work? how?)
You can't repeat main method. In Java main method is been executing only once. To repeate your code, you could wrap whole main method content to the infinite loop or move the content to the separate method and call it from the loop in the main method.
A the end of the program I used two methods to output a message. The
system.out.print works fine but the JOptionPane method doesn't display
the message and the program doesn't terminate (I have commented it
out). I would like to understand why?
JOptionPane works only for graphic application (Swing/AWT). This is not available in console. You have only standard input and output there.
Is the default case required in the switch? And Am I following the
correct code structure? (the arrangements and uses of curly braces)
No, default case is optional by JVM syntax. I remember, that e.g. in C++ there was reccomendation to place it (event empty), to exclude side effects of compilators. I do not know, is there such reccomendation in Java, but when I use switch, I prefer to always add it to exclude logical problem (but this is definetly optional according to syntax case). You use switch correctly.
public static void main(String[] args) {
System.out.println("This is a simple calculator that will do basic calculations such as :"
+ "\nAddition (+)"
+ "\nMultiplication (*)"
+ "\nSubtraction (-)"
+ "\nDivision (/)");
System.out.println();
try (Scanner scan = new Scanner(System.in)) {
while (true) {
System.out.println("Enter Any positive number followed by pressing ENTER.");
int first = scan.nextInt();
System.out.println("Enter a valid OPERATOR (+,*,-,/) sign followed by pressing ENTER.");
String operator = scan.next();
while (operator.length() != 1 || !"+*-/".contains(operator)) {
System.out.println("Please Re-enter a valid Operator (+,-*,/)");
operator = scan.next();
}
scan.nextLine();
System.out.println("Enter your Second number followed by an ENTER stroke.");
int second = scan.nextInt();
if ("+".equals(operator))
System.out.println("The Resulting sum is " + (first + second));
else if ("*".equals(operator))
System.out.println("The Resulting mul is " + (first * second));
else if ("-".equals(operator))
System.out.println("The Resulting sub is " + (first - second));
else if ("/".equals(operator))
System.out.println("The Resulting div is " + ((double)first / second));
System.out.println();
System.out.println("Do you want to exit ('y' to exit)?");
if ("y".equals(scan.next()))
return;
System.out.println();
}
}
}
1) you can check size of string input.next() .If it is one then continue else again prompt for operator choice .
2)I would suggest better create a different method and put all logic in it and call it the number of time you want or call infinite number of times.
4)Should switch statements always contain a default clause?
If I run this code
Scanner sc = new Scanner();
while (true) {
if (sc.next().equals("1"))
System.out.println("--1--");
else if (sc.next().equals("2"))
System.out.println("--2--");
else if (sc.next().equals("3"))
System.out.println("--3--");
else if (sc.next().equals("4"))
System.out.println("--4--");
else if (sc.next().equals("help"))
System.out.println("--help--");
}
It will not read the first time I type enter. I have to type 2-4 times before it reads the input. A session could look like this:
1
1
1
1
--1--
3
3
--3--
help
2
1
help
--help--
No matter what I type, it will only read the last input of the four inputs.
Sometimes it reads after two inputs. I'm really confused about this.
Should I instead use multiple scanners?
Your concepts are wrong here.
Each time you ask for sc.next() it will wait for the input. If that input is equal to what you want it to be, then the code is executed.
You can correct this by storing sc.next() in a String variable, and then comparing it.
Here:
if (sc.next().equals("1"))
it asks for an input.
If that input is 1 then the code is executed and --1-- is printed out. Else, it jumps to this: if (sc.next().equals("2")). Now if the input is 2 then the code to print --2-- is executed. Else, it jumps to if (sc.next().equals("3")) and so on.
You can correct this by:
storing sc.next() in a String variable, and then comparing it.
using a switch-case block to compare the input.
You're calling sc.next() multiple times - so if the input isn't 1, it's going to wait for more input to see whether the next input is 2, etc. Each call to sc.next() will wait for more input. It doesn't have any idea of "that isn't the input you were looking for, so I'll return the same value next time you call".
Use a local variable to store the result of sc.next()
while (true) {
String next = sc.next();
if (next.equals("1"))
System.out.println("--1--");
else if (next.equals("2"))
System.out.println("--2--");
else if (next.equals("3"))
System.out.println("--3--");
else if (next.equals("4"))
System.out.println("--4--");
else if (next.equals("help"))
System.out.println("--help--");
}
Also consider using a switch statement instead...
You are calling sc.next() multiple times
Solution code :
Scanner scanner = new Scanner(System.in);
while(true){
switch (scanner.next()) {
case "1":
System.out.println("--1--");
break;
case "2":
System.out.println("--2--");
break;
case "3":
System.out.println("--3--");
break;
case "4":
System.out.println("--4--");
break;
case "help":
System.out.println("--help--");
break;
default:
break;
}
}
I am doing a coding project for a basic non recursive, non GUI form of Minesweeper. One of the requirements is that input commands must be strictly formatted like so:
For marking commands (reveal, guess, mark):
["reveal"/"r"] [int] [int]
For help and quit:
just ["help"/"h"] or ["quit"/"q"]
Any inputs outside of these restrictions must be considered ill-formatted. My code for reveal looks something like this:
case "reveal":
case "r":
roundsCompleted ++;
if(input.hasNextInt()){
par1 = input.nextInt();
}
else{
commandIn = null;
}
if(input.hasNextInt()){
par2 = input.nextInt();
correctInput = true;
}
else{
commandIn = null;
}
if(correctInput && isInBounds(par1, par2)){
reveal(par1, par2);
where this is all inside a switch statement of course. The commandIn = null statements are designed to throw the default case which prints "command not recognized". I realize part of my issue here is that these are in two separate if-else statements. Another problem is that input.hasNextInt() doesn't seem to evaluating to false when there is not an int after the first one.
The essence of this problem is in completely restricting these commands to the formats I listed above. Can anyone give me some insight into this issue? Thanks.
I'd use regex to first see if something is either a good input or not just cause it'd be easier
String input = "r 3 4";
if (input.matches("^(help|h|quit|q|((r|reveal) \\d \\d))$"))
//switch case
System.out.println("match");
else
//null string
System.out.println("no match");
then after you've got a match you can use your switch case like what you're doing, if it's a "reveal" or "r", I would just use split() and turn it into an array to get the different x and y coordinates
its only my second program with java and im running into some issues.
I'm trying to get input from a user, either yes or no, then based on that go to an if else statemene. Heres what I have so far
String answer= UI.askString("Do you want to continue?");
if(answer=="yes"){
UI.println("Lets go");
}
else if(answer == "no"){
UI.println("Thank you. Goodbye");
}
else{
UI.println("Please enter yes or no");
}
Im thinking perhaps its better to use booleans for this?
Any help is gladly appreciated!
(also if you're wondering, its a custom import hence the weird syntax in some lines)
Cheers.
When you compare two Strings in Java with the == operator, they are compared to see if they are the same object, rather than whether they contain the same text. So, you could type "yes", and when you use if (answer == "yes") the comparison fails, because the object you got back from UI.askString is a different object, stored at a different place in memory, than the String the compiler generated from the literal "yes".
To compare the value of the two Strings you need to write answer.equals("yes"), or "yes".equals(answer). Either one will work, and will call the equals method of the String class, which will compare the actual text.
The latter syntax, "yes".equals(answer), is often recommended because it will not cause a NullPointerException, even if the variable answer is set to null. This is because the equals method handles null and simply returns false. If, on the other hand, you used the answer.equals("yes") form, and answer was null, you would be trying to invoke a method on null and an exception would be thrown.
what you are looking for is a dialog box. Here is oracle examples, with code. It is more than I can write here. There are ton of yes, no boxes and detection's of user input with them.
http://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html
Quick answer:
int dialogResult = JOptionPane.showConfirmDialog (null, "Would You Like to Save your Previous Note First?","Warning",dialogButton);
if(dialogResult == JOptionPane.YES_OPTION){ ... }
Other choices ...
YES_OPTION, NO_OPTION, CANCEL_OPTION, OK_OPTION, and CLOSED_OPTION
For a command line program you need...
import java.util.Scanner;
The code will look like ...
Scanner in = new Scanner(System.in);
String line = in.nextLine();
//ask them to write yes, no, whatever
if(line.equal("yes"){ }
else if (line.eqals("no") {}
else {}
using MikeG010590's answer, you can try:
Scanner in = new Scanner(System.in);
String line;
System.out.println("you want to continue?");
Boolean exit = null;
do {
line = in.nextLine();
switch (line) {
case "yes":
exit = false;
break;
case "no":
exit = true;
break;
default:
System.out.println("Please enter yes or no");
break;
}
}
while (exit == null);
System.out.println(exit ? "Thank you. Goodbye" : "Lets go");
I'm having trouble with passing a string and double to another class because it keeps on crashing at double cost = input.nextDouble();. Also, i was wondering if i am correct with the appending method used in public boolean addPARTDETAILS(String partDESCRIPTION, double partCOST).
For example. If the user enters the parts and cost, i want it to store that in a list and print it out with the cost appended.
Parts used:
brake pads ($50.00)
brake fluids ($25.00)
Note. Assuming that i have declared all variables and the array.
System.out.print("Enter registration number of vehicle");
String inputREGO = input.next();
boolean flag = false;
for(int i=0; i<6; i++){
if(inputREGO.equalsIgnoreCase(services[i].getregoNUMBER())){
System.out.print("Enter Part Description: ");
String parts = input.nextLine();
double cost = input.nextDouble();
services[i].addPARTDETAILS(parts, cost);
//System.out.println(services[i].getregoNUMBER());
flag = true;
}
}if(flag==false);
System.out.println("No registration number were found in the system.");
public boolean addPARTDETAILS(String partDESCRIPTION, double partCOST){
if(partDESCRIPTION == "" || partCOST <= 0){
System.out.println("Invalid input, please try again!");
return false;
}
else{
partCOST=0;
StringBuffer sb = new StringBuffer(40);
String[] parts = new String[50];
for (int i=0;i<parts.length;i++){
partDESCRIPTION = sb.append(partCOST).toString();
}
System.out.println(partDESCRIPTION);
totalPART+=partCOST;
return true;
}
}
it keeps on crashing at double cost = input.nextDouble();.
It is highly unlikely that your JVM is crashing. It is far more likely that you are getting an Exception which you are not reading carefully enough and have forgotten to include in your question.
It is far more likely your code is incorrect as you may have mis-understood how scanner works. And so when you attempt to read a double, there is not a double in the input. I suspect you want to call nextLine() after readDouble() to consume the rest of the the line.
I suggest you step through the code in your debugger to get a better understanding of what it is really doing.
Just to expand a bit on Joop Eggen's and Peter Lawrey's answers because I feel some may not understand.
nextLine doesn't play well with others:
nextDouble is likely throwing a NumberFormatException because:
next, nextInt, nextDouble, etc. won't read the following end-of-line character, so nextLine will read the rest of the line and nextDouble will read the wrong thing.
Example: (| indicates current position)
Start:
|abc
123
def
456
After nextLine:
abc
|123
def
456
After nextDouble:
abc
123|
def
456
After nextLine (which reads the rest of the line, which contains nothing):
abc
123
|def
456
Now nextDouble tries to read "def", which won't work.
If-statement issues:
if(flag==false);
or, rewritten:
if(flag==false)
;
is an if statement with an empty body. Thus the statement following will always execute. And no need to do == false, !flag means the same. What you want:
if (!flag)
System.out.println("No registration number were found in the system.");
String comparison with ==:
partDESCRIPTION == ""
should be:
partDESCRIPTION.equals("")
or better:
partDESCRIPTION.isEmpty()
because == check whether the strings actually point to the exact same object (which won't happen unless you assign the one to the other with = at some point, either directly or indirectly), not just whether the have the same text (which is what equals is for).
Data dependent error.
if(flag==false);
System.out.println("No registration number were found in the system.");
should be (because of the ;):
if (!flag) {
System.out.println("No registration number was found in the system.");
}
And
partDESCRIPTION == ""
should be:
partDESCRIPTION.isEmpty()