Java Exception problem with scanner and method - java

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.

Related

Trying to stop a Do-While Loop for an application

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));
}

What is wrong with this java while loop?

New to Java and learning how to use While loops and random generator. This prints a multiplication question. Every time the user answers a question wrong, it should print the same question. Instead, it exits the program. What should I do?
while (true) {
Random multiply = new Random();
int num1 = multiply.nextInt(15);
int num2 = multiply.nextInt(15);
int output = num1 * num2;
System.out.println("What is the answer to " + num1 + " * " + num2);
Scanner input = new Scanner(System.in);
int answer = input.nextInt();
if (answer == output) {
if (answer != -1)
System.out.println("Very good!");
} else {
System.out.println("That is incorrect, please try again.");
}
}
If you want to repeat the same question when the user gets the answer wrong, you should use another while inside your main loop.
This inner loop continues to ask as long as you give a wrong answer.
I also replaced nextInt with nextLine, which reads in a whole line of text. This consumes the "Enter" key and is a safer approach at reading from the console. Since the result is now a String you need to use Integer.parseInt to convert it to an int. This throws an exception if you enter anything but a whole number so I wrapped it into a try-catch block.
If you want, you can add an additional check for validating user input. So in case the user wants to stop playing they only need to input "exit" and the whole outer loop will exit.
boolean running = true; // This flag tracks if the program should be running.
while (running) {
Random multiply = new Random();
int num1 = multiply.nextInt(15);
int num2 = multiply.nextInt(15);
int output = num1 * num2;
boolean isCorrect = false; // This flag tracks, if the answer is correct
while (!isCorrect) {
System.out.println("What is the answer to " + num1 + " * " + num2);
Scanner input = new Scanner(System.in);
try {
String userInput = input.nextLine(); // Better use nextLine to consume the "Enter" key.
// If the user wants to stop
if (userInput.equals("exit")) {
running = false; // Don't run program any more
break;
}
int answer = Integer.parseInt(userInput);
if (answer == output) {
if (answer != -1) {
System.out.println("Very good!");
isCorrect = true; // Set the flag to true, to break out of the inner loop
}
} else {
System.out.println("That is incorrect, please try again.");
}
}
catch(NumberFormatException e) {
System.out.println("Please enter only whole numbers");
}
}
}
Avoid while true. Declare a variable to true, pass the variable to the condición loop and set it to false when the answer is incorrect. You can use break too, but is easier to read the code when you use a exit condition in the while. Also read more about loops https://docs.oracle.com/javase/tutorial/java/nutsandbolts/while.html

try catch in a do while loop

The program asks for the user input for the double num 1 and double num 2
and if there is an exception I want it to ask again for the input of num 1 and num 2
public static void main (String[] args) {
Scanner sc = new Scanner(System.in);
double num1, num2;
int error = 0;
int text;
System.out.print("Enter 4 ");
text = sc.nextInt();
do{
try{
if(text == 4){
System.out.print("Enter number 1: ");
num1 = sc.nextDouble();
System.out.print("Enter number 2: ");
num2 = sc.nextDouble();
double quotient = num1/num2;
System.out.println("The Quotient of "+num1 + "/" +num2+ " = "+quotient);
}
}catch(Exception ex){
System.out.println("You've entered wrong input");
error = 1;
}
}while(error == 1);
}
then when I try the code if it will catch the exceptions by inputing string in the num1 or num 2 I'm having this infinite loop :
Enter number 1: You've entered wrong input
Enter number 1: You've entered wrong input
Enter number 1: You've entered wrong input
Enter number 1: You've entered wrong input
Enter number 1: You've entered wrong input
You need to reset the error variable inside the loop
do {
error = 0;
//...
} while(error == 1);
It is not necessary to utilize exception handling. Just use Scanner.hasNextDouble() method to find out if actual user input is double, otherwise continue the cycle.
package com.company;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
double num1, num2;
num1 = readDouble(1, sc);
num2 = readDouble(2, sc);
double quotient = num1/num2;
System.out.println("The Quotient of " + num1 + "/" + num2 + " = " + quotient);
}
private static double readDouble(int i, Scanner sc) {
while (true) {
System.out.print("Enter number " + i + ": ");
if (!sc.hasNextDouble()) {
System.out.println("You've entered wrong input");
sc.next();
continue;
}
break;
}
return sc.nextDouble();
}
}
Its in C# but relatively similar :)
public class Program
{
private static double ReadUserInput (string message)
{
// This is a double
// The '?' makes it nullable which is easier to work with
double? input = null;
do
{
// Write message out
Console.Write(message);
// Read answer
var inputString = Console.ReadLine();
// Temp variable for the number
double outputNumber = 0;
// Try parse the number
if (double.TryParse(inputString, out outputNumber))
{
// The number was parsable as a double so lets set the input variable
input = outputNumber;
}
else
{
// Tell the user the number was invalid
Console.WriteLine("Sorry bud, but '" + inputString + "' is not a valid double");
}
}
while (input == null); // Keep running until the input variable is actually set by the above
// Return the output
return (double)input;
}
public static void Main()
{
// Read a number
var num1 = ReadUserInput("Enter number 1:");
// Read another number
var num2 = ReadUserInput("Enter number 2:");
// Show the calculation
Console.WriteLine("Answer: " + (num1*num2));
}
}
Demo
And for the actual code (in JAVA):
public class JavaFiddle
{
public static void main (String[] args)
{
// Read a number
Double num1 = ReadUserInput("Enter number 1:");
// Read another number
Double num2 = ReadUserInput("Enter number 2:");
// Show the calculation
System.out.println("Answer: " + (num1*num2));
}
public static Double ReadUserInput (String message)
{
java.util.Scanner inputScanner = new java.util.Scanner(System.in);
Double input = null;
do
{
// Write message out
System.out.println(message);
// Read answer
String inputString = inputScanner.nextLine();
try
{
// Try parse the number
input = Double.parseDouble(inputString);
}
catch (NumberFormatException e)
{
// Tell the user the number was invalid
System.out.println("Sorry bud, but '" + inputString + "' is not a valid double");
}
}
while (input == null); // Keep running until the input variable is actually set by the above
// Return the output
return input;
}
}
You probably want to test if there is no error:
}while(error != 1);
or
}while(error == 0);
You'll need a method for the input which calls itself, if the input is invalid.
double getInput(Scanner sc) {
try {
double num = sc.nextDouble();
return num;
} catch(Exception ex) {
System.out.println("You've entered wrong input");
return getInput(sc);
}
}
And call this method twice in your other method.
it may look ugly , but here is a way to do it
do
{
if(...)
{
boolean successReading = false;
while(!successReading)
{
try
{
System.out.print("Enter number 1: ");
num1 = sc.nextDouble();
System.out.print("Enter number 2: ");
num2 = sc.nextDouble();
successReading = true;
double product = num1*num2;
}
catch(Exception e)
{
successReading = false;
}
}
}
}while(...)
You need to add sc.next(); inside catch block.
nextDouble method doesn't clear buffer in case of exception. So next time you invoke it you get same error because old input is still in buffer.
Also you need to reset your error flag in the beginning of the loop.
You have to put sc.next(); in the catch so it will clear your scanner variable and it will ask for an input

How do I make my do while loop with user prompt work?

I'm creating an application that basically works as a guessing game. At the end of the game I want to ask the user if they want to play again. If they type "Y" or "y", the game will restart, if any other character is entered, then the loop ends.
public class NumberGame {
public static void main(String[] args) throws java.io.IOException {
int NumberGame;
int NumberUser;
char BonusResponse;
char charGen;
String Guess = " ";
String Bonus = " ";
do {
NumberGame = (int) (Math.random() * 10);
charGen = (char)(NumberGame + 48);
//for(NumberGame < 1; NumberGame++){
System.out.print("The computer generated number was " + NumberGame);
System.out.print("\nGuess a number between 1 and 9: ");
NumberUser = (char) System.in.read();
NumberUser = (int) (NumberUser - 48);
if (NumberGame > NumberUser)
Guess = " Too low! Try again";
else if (NumberGame == NumberUser)
Guess = " Congratulations, you win!";
else if (NumberGame < NumberUser)
Guess = " Too high! Try again";
System.out.println("You guessed " + NumberUser + "." + Guess);
if (NumberGame == NumberUser)
Bonus = "Now that you've won, wanna play again? Type Y to play again or any other key to exit:";
else
Bonus = " ";
System.out.println(Bonus);
BonusResponse = (char) System.in.read();
} while (BonusResponse == 'Y' || BonusResponse == 'y');
}
}
You could use the Scanner Class instead of plain System.in.read()
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
String response= sc.next();
You can use Scanner class as seen on this answer or BufferedReader as seen on this answer.
Example with BufferedReader class:
import java.io.BufferedReader;
import java.io.InputStreamReader;
class Areas {
public static void main(String args[]){
float PI = 3.1416f;
int r=0;
String rad; //We're going to read all user's text into a String and we try to convert it later
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //Here you declare your BufferedReader object and instance it.
System.out.println("Radius?");
try{
rad = br.readLine(); //We read from user's input
r = Integer.parseInt(rad); //We validate if "rad" is an integer (if so we skip catch call and continue on the next line, otherwise, we go to it (catch call))
System.out.println("Circle area is: " + PI*r*r + " Perimeter: " +PI*2*r); //If all was right, we print this
}
catch(Exception e){
System.out.println("Write an integer number"); //This is what user will see if he/she write other thing that is not an integer
Areas a = new Areas(); //We call this class again, so user can try it again
//You can also print exception in case you want to see it as follows:
// e.printStackTrace();
}
}
}
Example with Scanner class:
import java.util.Scanner;
public class Main{
public static void main(String args[]){
Scanner scan= new Scanner(System.in);
//For string
String text= scan.nextLine();
System.out.println(text);
//for int
int num= scan.nextInt();
System.out.println(num);
}
}
You can try adding the reading code inside a do-while loop to validate user input. Then add this code after your while (BonusResponse == 'Y' || BonusResponse == 'y');
if (BonusResponse == 'y' || BonusResponse == 'Y') {
startApplication();
}
move all your main() code to startApplication() method. And change main to:
public static void main(String args[]) {
startApplication();
}
Also please follow Java naming conventions:
Except for variables, all instance, class, and class constants are in
mixed case with a lowercase first letter. Internal words start with
capital letters. Variable names should not start with underscore _ or
dollar sign $ characters, even though both are allowed.

Java - String Input Exception Handling

I´m totally new to Java and I´m stuck. I have to create the game "guess the Number". I´m able to do the most parts but I´m don´t now how to handle the User Input if its a String.
I want to be able to tell the User that the Input was not correct if he enters a String, and repeatedly ask for Input. It would be great if someone could help me here :)
Here is my Code:
import java.util.Scanner;
import java.util.Random;
public class SWENGB_HW_2 {
public static void main(String[] args) {
System.out.println("Welcome to the guess the number game!\n");
System.out.println("Please specify the configuration of the game:\n");
Scanner input = new Scanner(System.in);
System.out.println("Range start number (inclusively):");
int startRange;
startRange = input.nextInt();
System.out.println("Range end (inclusively):");
int endRange;
endRange = input.nextInt();
System.out.println("Maximum number of attemps:");
int maxAttemp;
maxAttemp = input.nextInt();
System.out.println("Your Task is to guess the random number between "
+ startRange + " and " + endRange);
Random randGenerator = new Random();
int randNumber = randGenerator.nextInt((endRange - startRange) + 1)
+ startRange;
int numberOfTries = 0;
System.out
.println("You may exit the game by typing; exit - you may now start to guess:");
String exit;
exit = input.nextLine();
for (numberOfTries = 0; numberOfTries <= maxAttemp - 1; numberOfTries++) {
int guess;
guess = input.nextInt();
if (guess == randNumber) {
System.out.println("Congratz - you have made it!!");
System.out.println("Goodbye");
} else if (guess > randNumber) {
System.out.println("The number is smaller");
} else if (guess < randNumber) {
System.out.println("The number is higher");
}
}
if (numberOfTries >= maxAttemp) {
System.out.println("You reached the max Number of attempts :-/");
}
}
}
You can create a utility method that looks like this:
public static int nextValidInt(Scanner s) {
while (!s.hasNextInt())
System.out.println(s.next() + " is not a valid number. Try again:");
return s.nextInt();
}
and then, instead of
startRange = input.nextInt()
you do
startRange = nextValidInt(input);
If you want to deal with the "exit" alternative, I'd recommend something like this:
public static int getInt(Scanner s) throws EOFException {
while (true) {
if (s.hasNextInt())
return s.nextInt();
String next = s.next();
if (next.equals("exit"))
throw new EOFException();
System.out.println(next + " is not a valid number. Try again:");
}
}
and then wrap the whole program in
try {
...
...
...
} catch (EOFException e) {
// User typed "exit"
System.out.println("Bye!");
}
} // End of main.
Btw, the rest of your code looks great. I've tried it and it works like a charm :-)
You could check that the scanner has an int before you attempt to read it. You can do that by calling hasNextInt() with something like
while (input.hasNext() && !input.hasNextInt()) {
System.out.printf("Please enter an int, %s is not an int%n", input.next());
}
int startRange = input.nextInt();

Categories

Resources