Trying to stop a Do-While Loop for an application - java

I'm creating an application for a homework, the problem is that I am trying to create a do-while loop to exit the application (Using the question "Do you want to exit (Y/N)"). To work with the do-while loop, I created a method to store the app and then called the method in the do-while loop, so that when I try to stop the loop, the method loops once more. I want when I type "Y" to the console the whole program stops and doesn't loop one more time.
I created a simple example to explain my problem.
Here's the method:
public static void App(){
Scanner sc = new Scanner(System.in);
System.out.print("Write a number: ");
int num1 = sc.nextInt();
System.out.print("Write another number: ");
int num2 = sc.nextInt();
System.out.println("\nResult: "+(num1+num2));
}
And here I'm trying to create the loop in the main method:
public static void main(String[] args) {
Scanner sc2 = new Scanner(System.in);
App();
String answer;
do {
System.out.println("Do you want to exit (Y/N)?");
answer = sc2.next();
App();
} while (answer.equalsIgnoreCase("N")) ;
}

the problem is that I am trying to create a do-while loop to exit the application
You already have that in your program.
so that when I try to stop the loop, the method loops once more...
That doesn't fit the goal of your program.
I want when I type "Y" to the console the whole program stops and doesn't loop one more time
A lot of context that doesn't fit right in.
But anyway, you just have to reorganize your program.
In other words, just move your App() method.
public static void main(String[] args) {
Scanner sc2 = new Scanner(System.in);
String answer;
do {
App();
System.out.println("Do you want to exit (Y/N)?");
answer = sc2.next();
} while (answer.equalsIgnoreCase("N")) ;
}
Also, I spotted a lot of bad practices, so I kind of fixed them:
public static void main(String[] args) throws Exception {
try(Scanner sc2 = new Scanner(System.in)){
String answer;
do {
App();
System.out.print("Do you want to exit (Y/N)?");
answer = sc2.nextLine();
} while (answer.equalsIgnoreCase("N")) ;
}
}
Lastly, maybe (just maybe) try to solve your problem first before seeking help for your homework.

The reason why your program is running again after you type n is because the App() method is ran after the question is asked within the do part of the loop.
This code below is the simplest fix I could think of.
public static void main(String[] args) {
Scanner sc2 = new Scanner(System.in);
// I removed the line 'App();' as the App method will always run at least one time. Therefore putting that method within the 'do' part of the loop allows us to ask the user if they wish to exit or not after they have received their answer.
String answer;
do {
App();
System.out.print("Do you want to exit (Y/N)?"); //I changed the 'println' to 'print' here
answer = sc2.next();
} while (answer.equalsIgnoreCase("N")) ;
}
As a side note, methods in java should be lower-case when following typical Java naming conventions. While this will not affect how your code runs, I would suggest renaming the method from App() to app().

Everything looks good in your code, Just change the execution logic as shown in code blocks.
public static void main(String[] args) {
Scanner sc2 = new Scanner(System.in);
App(); //remove this line from here
String answer;
do {
App(); //call App function here so that it got executed at least one time
System.out.println("Do you want to exit (Y/N)?");
answer = sc2.next();
App(); //remove this as well
} while (answer.equalsIgnoreCase("N")) ;
}

Here is yet another approach except it uses a while loops instead of do/while loops. Two different approaches are provided and both provide User entry validation:
Approach #1:
public static void appMethod() {
Scanner sc = new Scanner(System.in);
int num1 = Integer.MIN_VALUE; // Initialize with some obscure value.
int num2 = Integer.MIN_VALUE; // Initialize with some obscure value.
while (num1 == Integer.MIN_VALUE) {
System.out.print("Write a number: ");
try {
num1 = sc.nextInt();
} catch ( java.util.InputMismatchException ex) {
System.out.println("Invalid Entry! Try again..."
+ System.lineSeparator());
sc.nextLine(); // consume the ENTER key hit otherwise this error will keep cycling.
num1 = Integer.MIN_VALUE;
}
}
while (num2 == Integer.MIN_VALUE) {
System.out.print("Now, write yet another number: ");
try {
num2 = sc.nextInt();
} catch ( java.util.InputMismatchException ex) {
System.out.println("Invalid Entry! Try again..."
+ System.lineSeparator());
sc.nextLine(); // consume the ENTER key hit otherwise this error will keep cycling.
num2 = Integer.MIN_VALUE;
}
}
System.out.println("\nResult: " + num1 +" + " + num2 + " = " + (num1 + num2));
}
Approach #2:
This next approach makes use of the Scanner#nextLine() method. The thing to remember about nextLine() is that, if you use it in your console application then basically recommend you use it for everything (all prompts). A 'quit' mechanism is also available in this version. Read the comments in code:
public static void appMethod() {
Scanner sc = new Scanner(System.in);
// Retrieve first number...
String num1 = "";
while (num1.isEmpty()) {
System.out.print("Write a number (q to quit): ");
// Making use of the Scanner#nextLine() method
num1 = sc.nextLine();
// Has 'q' been supplied to Quit?
if (num1.equalsIgnoreCase("q")) {
return;
}
/* Validate the fact that a signed or unsigned Integer or
Floating Point value has been entered. If not show Msg. */
if (!num1.matches("-?\\d+(\\.\\d+)?")) {
System.out.println("Invalid Entry! (" + num1 + ") Try again..."
+ System.lineSeparator());
num1 = ""; // empty num1 so as to re-loop.
}
}
// Retrieve second number...
String num2 = "";
while (num2.isEmpty()) {
System.out.print("Now, write yet another number (q to quit): ");
num2 = sc.nextLine();
if (num2.equalsIgnoreCase("q")) {
return;
}
if (!num2.matches("-?\\d+(\\.\\d+)?")) {
System.out.println("Invalid Entry! (" + num2 + ") Try again..."
+ System.lineSeparator());
num2 = "";
}
}
// Convert the numerical strings to double data type values.
double number1 = Double.parseDouble(num1);
double number2 = Double.parseDouble(num2);
// Display the result.
System.out.println("\nResult: " + num1 +" + " + num2 + " = " + (number1 + number2));
}

Related

Java Exception problem with scanner and method

I've got some problems in java with putting scanner after an output, in a while loop.
the scanner scans which method to go and then when it comes back to the start of the loop
reset the variable.
I've already tried this and failed to find any understandable solution (I'm really new to java, and it is hard for me),
or to solve it myself.
here is the full code (i know the code is not so efficient):
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int con = 1;
System.out.println("Hey!,welcome to my games!");
Scanner scanner = new Scanner(System.in);
String game;
while (con == 1) {
System.out.println(
"Here Some games i have(Enter the text for the one you want):\nto stop=0\n1)calculator=1\n2)!Soon! Random numbers");
game = scanner.nextLine();
calculator();
scanner.reset();
System.out.println(game);
// if(game.equals("0")) {
// con=0;
// }
// else if(game.equals("1")) {
// System.out.println("Welcome Back!");
// }
// else {
// System.out.println("There is a mistake in your text");
// }
}
scanner.close();
}
static void calculator() {
int num1, num2, con = 1, stop = 1;
String op, ad = "add", su = "sub", mul = "multi", di = "div";
Scanner af = new Scanner(System.in);
while (con == 1) {
stop = 1;
System.out.println("Write number 1");
num1 = af.nextInt();
System.out.println("Write number 2");
num2 = af.nextInt();
System.out.println(
"Write an operation (one of these):\nAddition=add\nSubtraction=sub\nMultiplication=multi\nDivision=div");
op = af.next();
op = op.toLowerCase();
int minus = num1 - num2;
int plus = num1 + num2;
if (op.equals(ad)) {
System.out.println("The Operation is:Addition\n" + num1 + "+" + num2 + "=" + plus);
} else if (op.equals(su)) {
System.out.println("The Operation is:Subtraction\n" + num1 + "-" + num2 + "=" + minus);
} else if (op.equals(mul)) {
System.out.println("The Operation is:Multiplication\n" + num1 + "*" + num2 + "=" + num1 * num2);
} else if (op.equals(di)) {
System.out.println("The Operation is:Division\n" + num1 + "/" + num2 + "=" + num1 / num2);
} else {
System.out.println("Um,Did you make a mistake in your text?\nDo you want the calculator again?");
String yn = af.next();
yn = yn.toLowerCase();
if (yn.equals("yes") || yn.equals("yep")) {
stop = 0;
}
}
if (stop == 1) {
con = 0;
}
}
af.close();
}
}
as you can see, I tried myself to solve it and even put a comment on some of the code,
but when it runs to the method and comes back, it fails because the scanner thinks there is
something to scan before I wrote something. here is the exception-
Exception in thread "main" java.util.NoSuchElementException
at java.base/java.util.Scanner.throwFor(Scanner.java:937)
at java.base/java.util.Scanner.next(Scanner.java:1478)
at Main.main(Main.java:12)
You need a mechanism to loop-back (i.e. ask the user to enter the data again) in case of an invalid entry. One of the most common ways is to use do-while loop which guarantees to execute its body at least once. Check this tutorial to learn more about it.
Use Scanner::nextLine instead of Scanner::next, Scanner::nextInt etc. because they do not consume the newline character, created by hitting Enter key, from the input. Check this discussion to learn more about it.
Last but not least, never close a Scanner for System.in as it also closes System.in and there is no way to open it again without restarting the JVM. Note: If you are using Scanner to scan a File, make sure to close it in order to release the resource.
Demo:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int option;
boolean valid;
Scanner input2 = new Scanner(System.in);
do {
valid = true;
System.out.println("Choose an option:\n" + "1-Addition\n" + "2-Subtraction\n" + "3-Exit");
try {
option = Integer.parseInt(input2.nextLine());
if (option < 1 || option > 3) {
throw new IllegalArgumentException();
}
// ...Place here the rest of code (which is based on the value of option)
} catch (IllegalArgumentException e) {
System.out.println("This is an invalid entry. Please try again.");
valid = false;
}
} while (!valid);
}
}
A sample run:
Choose an option:
1-Addition
2-Subtraction
3-Exit
x
This is an invalid entry. Please try again.
Choose an option:
1-Addition
2-Subtraction
3-Exit
10.5
This is an invalid entry. Please try again.
Choose an option:
1-Addition
2-Subtraction
3-Exit
1
Did you remember to import java.util.Scanner?
Or how do you compile your source file?
I had that same error message when compiled with gradle and i was missing one tiny line in gradle build file.

How can I read any user input from the scanner library?

I'm fairly new to java, so don't think this is some idiot. Anyways, I've been trying to make a program that can read a certain letter from the console and then decide which operation to use, let's say to add. However, I can't get an If loop to read the variable that decides which operator to use, here is the code, and please help.
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner user_input = new Scanner( System.in );
int number;
String function;
System.out.println("What Do You Want to Do? (a to add; s to" +
" subrtact; d to divited; m to multiply, and sq to square your nummber.)" );
function = user_input.next();
if (function == "sq"){
System.out.print("Enter your number: ");
number = user_input.nextInt();
System.out.print(number * number);
} else {
System.out.println("Unidentified Function!");
}
}
}
(I made the description shorter so that it would fit).
This is just an example to get you started in the right direction.
import java.util.Scanner;
public class Example {
public static void main(String[] args) {
Scanner user_input = new Scanner(System.in);
int num1, num2, result;
System.out.println("What Do You Want to Do? (a to add; s to"
+ " subrtact; d to divited; m to multiply, and s to square your nummber.)");
String choice = user_input.next();
// Add
if (Character.isLetter('a')) {
System.out.println("Enter first number: ");
num1 = user_input.nextInt();
System.out.println("Enter second number: ");
num2 = user_input.nextInt();
result = num1 + num2;
System.out.println("Answer: " + result);
}
}
}
If you use hasNext() on a scanner it will wait for an input until you stop the program. Also using equals() is a better way of comparing strings.
while(user_input.hasNext()){
function = user_input.next();
if (function.equals("s")){
System.out.print("Enter your number: ");
number = user_input.nextInt();
System.out.print(number * number);
} else {
System.out.println("Unidentified Function!");
}
}
Scanner s = new Scanner(System.in);
String str = s.nextLine();
int a=s.nextInt();
int b=s.nextInt();
if(str.equals("+"))
c=a+b;
else if(str.equals("-"))
c=a-b;
else if(str.equals("/"))
c=a/b;
// you can add operators as your use
else
System.out.println("Unidentified operator" );
I hope it helps!

How to make a program run a second time?

import java.util.Scanner;
public class Dice {
public static void main(String[] args) {
//I used 'print' instead of 'println' just to make it look a little cleaner in the console.
System.out.print("Input your first number: ");
Scanner sc1 = new Scanner(System.in);
double num1 = sc1.nextInt();
//I use doubles for my variables just in case the user wants to divide.
System.out.print("Input your second number: ");
Scanner sc2 = new Scanner(System.in);
double num2 = sc2.nextInt();
/* I used words rather than the actual symbols for my operators just to get practice using scanners for strings.
* Until now I'd solely been using them for int variables. And also due to the small detail that before programming,
* I had no idea what a modulo was and I felt that would be confusing to a random person.
*/
System.out.println("What would you like to do with these numbers?(Add, Subtract, Multiply, Divide, or Check Divisibility): ");
System.out.println("Simply type 'check' to check the divisibility of your two numbers.");
Scanner sc3 = new Scanner(System.in);
String str1 = sc3.nextLine().toUpperCase();
/* toUpperCase to prevent the user from creating an error by typing their in put in a 'unique' way.
*It took me several failures to finally look up toUpperCase.
*/
double num3;
switch(str1) {
case "ADD":
num3 = num1 + num2;
System.out.println("The sum is: " + num3);
break;
case "SUBTRACT":
num3 = num1 + num2;
System.out.println("The difference is: " + num3);
break;
case "MULTIPLY":
num3 = num1 * num2;
System.out.println("The product is: " + num3);
break;
case "DIVIDE":
num3 = num1 / num2;
System.out.println("The quotient is: " + num3);
break;
case "CHECK":
num3 = num1 % num2;
System.out.println("The remainder is: " + num3);
break;
default:
System.out.println("Invalid input. Please ensure that two numbers were entered and that you entered a valid math operation.");
break;
}//switch statement
}//main method
}//class
How would I get my code to run again if I wanted to maybe add another number to my answer? I'm just trying to get some practice in with my Java (I'm extremely green) and I apologize in advance if my question is too broad.
Consider the following small program
boolean quit = false;
while(!quit) {
System.out.print("Enter Something:");
Scanner sc1 = new Scanner(System.in);
String input = sc1.nextLine();
if(input.compareToIgnoreCase("quit") == 0) {
quit = true;
continue;
}
System.out.println("You entered " + input);
}
In this sample we keep asking them to enter something and print it out unless that input is "quit" in that case we use the continue statement to skip the rest of the loop and go back to the top of the while loop and re-evaluate the condition for another iteration. If you entered 'quit' this will evaluate to false and stop the loop and exit the program.
Heres a sample input/output from the program. Notice there is no "You entered quit", this is because the continue statement brought us back to the top of the while loop.
Enter Something:hello
You entered hello
Enter Something:quit
Now how can you adapt this to your program? Heres a small sample of how you can do one of your inputs
double num1 = 0;
String input1 = sc1.nextLine();
if(input1.compareToIgnoreCase("quit") == 0) {
// quit was entered, leave the loop
quit = true;
continue;
}
try {
num1 = Double.parseDouble(input1);
} catch(NumberFormatException e) {
// user entered something that isnt a number, quit the program for now
// you can change this to whatever behavior you like in the future
quit = true;
continue;
}
This will likely leave you with some validation questions like "I want to have my user try again if they input an invalid number" Those are all possible using this method and it leads you in the right direction.
Remember, main() is a callable method. Instead of using a while or for loop, you could just call it again at the end of the main method method.
// Put this at the end of your main method
System.out.print("Do you want to execute again? (yes/no)");
boolean repeat = sc1.nextLine().toUpperCase().equals("YES");
if (repeat) {
main(null); // You're not using any arguments in main()
}
On a separate note, you don't need all three of sc1, sc2, and sc3. They're basically the same. You could probably use sc1 everywhere and remove sc2 and sc3 completely.
// something like this then ask if to do another run if not set flag false
boolean flag = true;
while(flag)
{
System.out.print("Input your first number: ");
Scanner sc1 = new Scanner(System.in);
double num1 = sc1.nextInt();
You should put all your logic around a while loop which will grant to you to repeat your task until a condition is reached.
Maybe you can ask to the user to insert the string "EXIT" when he wants to exit from your program.
In your case I'll do something like this:
boolean exitFlag = false;
do {
// <put your logic here>
String answer = sc3.nextLine().toUpperCase();
if (answer.equals("EXIT")) {
exitFlag = true;
}
} while(!exitFlag);

Java output error

I can't get this to work properly. It functions as it is supposed to, and does the math, but then it loops once, and ends. I need it to either loop until the users decides to end it, or only run once.
import java.util.Scanner;
public class java {
public static void main(String args[]) {
System.out.println("Welcome to the simple Calculator program");
System.out.println("Please type what type of math you would like to do: ");
System.out.println("1=Addition");
System.out.println("2=Subtraction");
System.out.println("3=Multiplication");
System.out.println("4=Division");
System.out.println("5=Sqrt");
Scanner input = new Scanner(System.in);
int math = input.nextInt();
if (math == 1) {
Scanner a = new Scanner(System.in);
int a1;
int a2;
int asum;
System.out.print("Please enter the first number: ");
a1 = a.nextInt();
System.out.print("Please enter the second number: ");
a2 = a.nextInt();
asum = a2 + a1;
System.out.print("The sum is: " + asum + "Thank You for using this program");
}
Scanner number = new Scanner(System.in);
int number1;
int number2;
int sum;
System.out.print("Enter first number: ");
number1 = number.nextInt();
System.out.print("Enter Second number: ");
number2 = number.nextInt();
sum = number1 + number2;
System.out.printf("Sum is %d\n", sum);
}
}
Use
do{
// do something.
} while(some condition);
And reapeat the same scanner to get input. You can also add one more option to your menu for repeating and evaluate that with while condition.
It is working as it should.
If you want it to loop as per some user input,you must use any looping construct like while.
Instead of if (math == 1) use
`while (math != exit)`
Make a new entry for exit like 0
Try using while loop. Give the user an option to quit the program.
import java.util.Scanner;
public class java
{
public static void main(String args[])
{
Scanner a = new Scanner(System.in);
System.out.println("Welcome to the simple Calculator program");
while(true)
{
System.out.println("Please type what type of math you would like to do: ");
System.out.println("1=Addition");
System.out.println("2=Subtraction");
System.out.println("3=Multiplication");
System.out.println("4=Division");
System.out.println("5=Sqrt");
System.out.println("6=Quit"); // added an option to quit the program
int math = a.nextInt();
if (math == 1)
{
int a1,a2,asum;
System.out.print("Please enter the first number: ");
a1 = a.nextInt();
System.out.print("Please enter the second number: ");
a2 = a.nextInt();
asum = a2 + a1;
System.out.println("The sum is: " + asum + "Thank You for using this program");
}
// Include actions for math = 2 to 5
if(math == 6)
{
System.out.println("Thank You for using this program");
System.exit(0);
}
}
}
}
The options are displayed again and again after each calculation until the user wants to exit the program by entering 6.
If you want the program to run only once, you should leave out the outer while loop. Everything else remains the same.
PS - You don't need to reopen Scanner again and again (at least not in this problem).
That is because you are only reading the input from the console once..you need to keep the console up with something like while(true) {} or monitor the console for an exit conditon like (" 0 = exit ") .
Also, I don''t think you will need to read two numbers again and again like you are doing right now.
1) You can use a do-while loop with a condition till which you wish to execute.
2) Use a switch case and perform the math operations inside the switch case with different operators. As of now you are trying to perform only addition. So you a switch case where you can perform all the operations.
3) In the switch case have an option which calls the exit(0) method. So that you can run the program until the user wish to exit.
4) By using a switch case you can make the user to choose his own option.
Your entire program is correct dude.
Just add
System.exit(0);
In every if(math==1) ,if(math==2)...before their statement ending.
like if(math==1)
{
...
System.exit(0);
}
You can fix your error...
Like me if your error is fixed. If not tell me the error

Java: Using scanner to read in boolean values failing.

import java.util.Scanner;
public class Cardhelp2{
private static String[] pairArray={"A,A","K,K","Q,Q","J,J","10,10","9,9","8,8","7,7","6,6","5,5","4,4","3,3","2,2"};
public static void generateRandom(int k){
int minimum = 0;
int maximum = 13;
for(int i = 1; i <= k; i++)
{
int randomNum = minimum + (int)(Math.random()* maximum);
System.out.print("Player " + i +" , You have been dealt a pair of: ");
System.out.println(pairArray[randomNum]);
}
} //reads array and randomizes cards
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("How many players would you like to play with? ");
int m = scan.nextInt();
generateRandom(m);
//displays the cards
___________________________________________________
System.out.println("Would you like to play?");
Scanner scanner = new Scanner(System.in);
if(scanner.next().equalsIgnoreCase("y")||scanner.next().equalsIgnoreCase("yes")) {
System.out.println("This will be fun");
} else if(scanner.next().equalsIgnoreCase("n")||scanner.next().equalsIgnoreCase("no")) {
System.out.println("Maybe next time");
} else {
System.out.println("Invalid character");
}
}
}
Im having trouble understanding why the end part is not working, I've been told i need to change scanner.next(); to a variable but im not sure how to do it and get the code working. Is there a simple way of reading in the users answer then displaying a response to the user?
Thanks
Your conditional expression
if(scanner.next().equalsIgnoreCase("y")||scanner.next().equalsIgnoreCase("yes"))
calls scanner.next() twice, which means the second call will read/wait for more input. Instead you need to call it only once, store the result and use that in the comparison:
String tmp = scanner.next();
if(tmp.equalsIgnoreCase("y")||tmp.equalsIgnoreCase("yes"))
Let's assume the user inputs "yes".
At
if(scanner.next().equalsIgnoreCase("y")||scanner.next().equalsIgnoreCase("yes")) {
Scanner.next() produces "yes" in the first test. So the code is effectively
"yes".equalsIgnoreCase("y")
Which is false, so it moves to the next test:
scanner.next().equalsIgnoreCase("yes")
Here's where your issue is.
the "yes" entered has already been consumed by the first test. Now the Scanner has nothing in the buffer.
If you want to test the SAME input again, you must capture it, and use that in your tests.
So
String userReply= Scanner.next();
if(userReply.equalsIgnoreCase("y")||userReply.equalsIgnoreCase("yes")) {...
This is becauswe, with each call to scanner.next(), the Scanner returns the next value in the stream, and then MOVES PAST IT
If the user had entered "yes" and then "no", the tests would be performed like this:
if("yes".equalsIgnoreCase("y")||"no".equalsIgnoreCase("yes")) {...
You need change the way of Scanner's calls.
The user input \n and Scanner seems don't follow with the next token. Then you need read line by line.
:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("How many players would you like to play with? ");
int m = Integer.parseInt(sc.nextLine()); // May thrown NumberFormatException
generateRandom(m);
//displays the cards
System.out.print("Would you like to play? ");
String input = sc.nextLine();
if (input.equalsIgnoreCase("y") || input.equalsIgnoreCase("yes")) {
System.out.println("This will be fun");
} else if (input.equalsIgnoreCase("n") || input.equalsIgnoreCase("no")) {
System.out.println("Maybe next time");
} else {
System.out.println("Invalid character");
}
}

Categories

Resources