This question already has answers here:
java.util.NoSuchElementException - Scanner reading user input
(5 answers)
Closed 4 years ago.
How do I resolve the java.util.NoSuchElementException error? I call the scanner object 3 times, and the program will accept input the first two times. But on the third try, I immediately get the java.util.NoSuchElementException error. The name of the scanner object is stdInput.
I've tried creating a new scanner object just for the instance throwing this error, but I still get the same error, just from a different line in the code.
/**
* reddit url: https://www.reddit.com/r/dailyprogrammer/comments/pjbj8/easy_challenge_2/
*/
import java.util.Scanner;
public class challenge {
public static void main(String[] args) {
int choiceNum = 0;
boolean continueRunningProgram = true;
String repeatProgram = "";
Scanner stdInput = new Scanner (System.in);
do {
System.out.println("Are you solving for force (1), mass (2), or acceleration (3)?");
choiceNum = stdInput.nextInt();
if(isValidChoiceNum(choiceNum) == false) {
do {
System.out.println("The number " + choiceNum + " is an invalid choice. Please choose again.");
choiceNum = stdInput.nextInt();
} while(isValidChoiceNum(choiceNum) == false);
}
switch(choiceNum) {
case 1:
System.out.println("The force is " + solvingForForce());
break;
case 2:
System.out.println("The mass is " + solvingForMass());
break;
case 3:
System.out.println("The acceleration is " + solvingForAcceleration());
break;
}
System.out.println("Would you like to solve another problem involving force, mass, and acceleration (Y/N)?");
repeatProgram = stdInput.next();
if(isValidChoiceChar(repeatProgram) == false) {
do {
System.out.println("The letter " + repeatProgram + " is an invalid choice. Please choose again.");
repeatProgram = stdInput.next();
} while(isValidChoiceChar(repeatProgram) == false);
}
if(repeatProgram.compareTo("Y") == 0) {
continueRunningProgram = true;
} else {
continueRunningProgram = false;
}
} while(continueRunningProgram == true);
stdInput.close();
} // end of main method
public static boolean isValidChoiceNum(int c) {
if(c < 1 || c > 3 ) {
return false;
} else {
return true;
}
}
public static boolean isValidChoiceChar(String c) {
if(c.compareTo("Y") == 0 || c.compareTo("N") == 0) {
return true;
} else {
return false;
}
}
public static double solvingForForce() {
Scanner stdInput2 = new Scanner (System.in);
System.out.println("Please enter a value for mass.");
double m = stdInput2.nextDouble();
System.out.println("Please enter a value for acceleration.");
double a = stdInput2.nextDouble();
stdInput2.close();
return m * a;
}
public static double solvingForMass() {
Scanner stdInput2 = new Scanner (System.in);
System.out.println("Please enter a value for force.");
double f = stdInput2.nextDouble();
System.out.println("Please enter a value for acceleration.");
double a = stdInput2.nextDouble();
stdInput2.close();
return f / a;
}
public static double solvingForAcceleration() {
Scanner stdInput2 = new Scanner (System.in);
System.out.println("Please enter a value for force.");
double f = stdInput2.nextDouble();
System.out.println("Please enter a value for mass.");
double m = stdInput2.nextDouble();
stdInput2.close();
return f * m;
}
} // end of class
Stop the madness of closing a Scanner linked to System.in! It will close the underlying stream (System.in), causing any other attempt to read from that Stream to throw an exception.
Yes you will get a warning, but it is safe to ignore that warning, or you can add
#SuppressWarnings("resource")
Scanner in = new Scanner(System.in);
To avoid it.
Remember, if you didn't open a resource, you shouldn't close it. Let the JVM close it when it terminates the program.
This also includes creating a Scanner(System.in) inside a try with resources block:
try(Scanner in = new Scanner(System.in)){
//Code...
}
This will implicitly close the stream at the end of the block.
From the Java tutorials:
The try-with-resources statement ensures that each resource is closed at the end of the statement.
Also you have several Scanner objects reading from System.in, which is bad practice. I would pass them to your methods as a parameter:
public static double solvingForMass(Scanner in) {
System.out.println("Please enter a value for force.");
double f = in.nextDouble();
System.out.println("Please enter a value for acceleration.");
double a = in.nextDouble();
return f / a;
}
Also just a note that if you are ever doing the structure of:
if(someBool)
return true;
else
return false;
It can be simplified to just
return someBool
So your isValidChoice() method can be simplified to:
public static boolean isValidChoiceChar(String c) {
return c.compareTo("Y") == 0 || c.compareTo("N") == 0;
}
Although note you can use the equals() and equalsIgnoreCase()methods to compareString`'s
Related
I'm trying to make a program where a user needs to input a random integer. If the user inputs a String I want an error message to pop out: "This is not a number" and after that restart the program until the user inputs a number. I got this so far and I'm stuck. I just get an error message if I input a string and program crashes.
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int number = 0;
do {
System.out.println("Input a number!");
number = scanner.nextInt();
if (!scanner.hasNextInt()) {
System.err.println("This is not a number");
}
} while (!scanner.hasNextInt());
System.out.println("You entered: " + number);
}
You're getting an InputMisMatchException because if you input a string into a scanner.nextInt(), it will immediately give an error and stop the program before it does anything else, so it won't reach your if statement. One way to get around this issue is to instead receive user input as a string, try to parse it for an int, and end the loop if it doesn't throw an exception. This is my implementation:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input = "";
int number = 0;
boolean end = true;
do {
System.out.println("Input a number!");
input = scanner.nextLine();
try {
number = Integer.parseInt(input);
end = true;
} catch(Exception e) {
System.err.println("This is not a number");
end = false;
}
} while (!end);
System.out.println("You entered: " + number);
}
See if the below code can help achieve what you want to do.
public class Solution {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String number;
do {
System.out.println("Input a number!");
number = scanner.next();
} while (!isNumeric(number));
System.out.println("You entered: " + number);
}
public static boolean isNumeric(final String str) {
// null or empty
if (str == null || str.length() == 0) {
return false;
}
return str.chars().allMatch(Character::isDigit);
}
}
This question already has answers here:
How to handle infinite loop caused by invalid input (InputMismatchException) using Scanner
(5 answers)
Closed 6 years ago.
im beginner in java programing, have task need to be completed and looking for some useful tips. writing program which requires from user correct Float input, if input is incorrect, program gives another chance until correct input, my problem is next, when i enter incorrect input it runs non stop,, any ideas?
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
float f = 0;
int x = 1;
do {
try {
System.out.print("Enter an float:");
f = in.nextFloat();
x =2;
} catch (InputMismatchException e) {
System.err.println("Incorrect entry.");
}
System.out.println("Your entry is:" + f);
}
while(x==1);
}
Do this and you will get the output you want from your program
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
float f = 0;
int x = 1;
do {
try {
System.out.print("Enter an float:");
f = in.nextFloat();
x = 2;
} catch (InputMismatchException e) {
System.err.println("Incorrect entry.");
in.next();
}
} while (x == 1);
System.out.println("Your entry is:" + f);
}
You just need to add in.next() in catch block to continue the process.
As an alternative to the accepted answer, you may want to :
1) Check that the next token is a float hasNextFloat()
2) If it isn't, swallow the whole line nextLine()
Scanner in = new Scanner(System.in);
float f = 0;
String entry;
int x = 1;
do {
System.out.print("Enter an float:");
if (in.hasNextFloat()) {
f = in.nextFloat();
entry = Float.toString(f);
x = 2;
} else {
entry = in.nextLine();
System.err.println("Incorrect entry.");
}
System.out.println("Your entry is: " + entry);
} while (x == 1);
This has the advantage of getting rid, of wrong input line having multiple tokens (e.g : "aa bb cc").
I am having a little bit of a problem here. I am trying to figure out how to catch the IllegalArgumentException. For my program, if the user enters a negative integer, the program should catch the IllegalArgumentException and ask the user if he/she wants to try again. But when the exception is thrown, it doesn't give that option. It just terminates. I tried to use the try and catch method but it doesn't work for me. How do I catch this particular exception to continue to run instead of terminating?
public static void main(String[] args) throws IllegalArgumentException
{
String keepGoing = "y";
Scanner scan = new Scanner(System.in);
while(keepGoing.equals("y") || keepGoing.equals("Y"))
{
System.out.println("Enter an integer: ");
int val = scan.nextInt();
if (val < 0)
{
throw new IllegalArgumentException
("value must be non-negative");
}
System.out.println("Factorial (" + val + ") = "+ MathUtils.factorial(val));
System.out.println("Another factorial? (y/n)");
keepGoing = scan.next();
}
}
}
and
public class MathUtils
{
public static int factorial(int n)
{
int fac = 1;
for(int i = n; i > 0; i--)
{
fac *= i;
}
return fac;
}
}
You need to add the try catch block inside the loop to continue the working for the loop. Once it hits the illegal argument exception catch it in catch block and ask if the user wants to continue
import java.util.Scanner;
public class Test {
public static void main(String[] args)
{
String keepGoing = "y";
populate(keepGoing);
}
static void populate( String keepGoing){
Scanner scan = new Scanner(System.in);
while(keepGoing.equalsIgnoreCase("y")){
try{
System.out.println("Enter an integer: ");
int val = scan.nextInt();
if (val < 0)
{
throw new IllegalArgumentException
("value must be non-negative");
}
System.out.println("Factorial (" + val + ") = "+ MathUtils.factorial(val));
System.out.println("Another factorial? (y/n)");
keepGoing = scan.next();
}
catch(IllegalArgumentException i){
System.out.println("Negative encouneterd. Want to Continue");
keepGoing = scan.next();
if(keepGoing.equalsIgnoreCase("Y")){
populate(keepGoing);
}
}
}
}
}
Hope this helps.
Happy Learning :)
I don't think you want your main() method to be throwing an exception. Typically, this is the kind of thing that you'd put in try and catch blocks.
Honestly though, for this sort of thing an if/else would work better. (Unless you're just doing this as a toy example, to learn exceptions.)
Make another method called getNumber() that throws the IllegalArgumentException, that returns an int. Then put it inside the try/catch in the main().
public static void main(String[] args)
{
String keepGoing = "y";
Scanner scan = new Scanner(System.in);
while(keepGoing.equals("y") || keepGoing.equals("Y"))
{
int val = 0;
boolean flag=true;
while(flag){
try{
System.out.println("Enter an integer: ");
val = scan.nextInt();
if (val < 0)
{
throw new IllegalArgumentException
("value must be non-negative");
}
flag = false;
} catch(IllegalArgumentException e){
System.out.println("value must be non-negative");
}
}
System.out.println("Factorial (" + val + ") = "+ MathUtils.factorial(val));
System.out.println("Another factorial? (y/n)");
keepGoing = scan.next();
}
}
}
I would suggest you add a test on the negative value and display your message on the spot, then use an else block. Also, you could use String.equalsIgnoreCase() in your loop test like
String keepGoing = "y";
Scanner scan = new Scanner(System.in);
while (keepGoing.equalsIgnoreCase("y")) {
System.out.println("Enter an integer: ");
int val = scan.nextInt();
if (val < 0) {
System.out.println("value must be non-negative");
} else { // <-- skip negative value
System.out.println("Factorial (" + val + ") = "
+ MathUtils.factorial(val));
}
System.out.println("Another factorial? (y/n)");
keepGoing = scan.next();
}
Also, an int factorial(int) method can only the first 12 correct values. You could use a long or a BigInteger like
public static BigInteger factorial(int n) {
BigInteger fac = BigInteger.ONE;
for (int i = n; i > 1; i--) {
fac = fac.multiply(BigInteger.valueOf(i));
}
return fac;
}
Similar to some other answers, I would say that your main() method should not throw an exception to display an error message to the user, because that is not the purpose of exception handling mechanisms in Java. Exception handling is designed to enable methods to signal that something happened that should not have happened, so the methods that call those methods will know that they need to deal with them. In general, exceptions are caught, not thrown, by main() methods and other user interface methods.
I would make the method factorial() throw the IllegalArgumentException, rather than your main() method in your program class. Your main() method should use try and catch to handle this exception. With this design, if someone else wanted to use your MathUtils class, they would know that your factorial() method throws an IllegalArgumentException (especially if you document your code with javadoc), and would write their code to handle the exception. In the current situation, if someone tries to call MathUtils.factorial(-1), the return value would be 1 because the for loop inside factorial() would not execute at all (because i is initially set to -1, which is not greater than 0).
This is how I would revise your code:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String keepGoing = "y";
while(keepGoing.equalsIgnoreCase("y")) {
try { // This code might throw an exception
System.out.println("Enter an integer: ");
int val = scan.nextInt();
System.out.println("Factorial (" + val + ") = "+ MathUtils.factorial(val));
System.out.println("Another factorial? (y/n)");
keepGoing = scan.next();
} catch (IllegalArgumentException | InputMismatchException e) {
/* An InputMismatchException is thrown if the input is not an integer.
See the documentation for Scanner method nextInt() for more details.
*/
System.out.println("You must enter a non-negative integer.");
System.out.println("Try again? (y/n)");
keepGoing = scan.next();
}
}
}
}
and
public class MathUtils throws IllegalArgumentException {
public static int factorial(int n) {
if (fac < 0) {
throw new IllegalArgumentException("value must be non-negative");
}
int fac = 1;
for(int i = n; i > 0; i--) {
fac *= i;
}
return fac;
}
}
I a making a program that will ask an int input from user and check whether user input is an integer or not. If no the program asks for an input tile it gets a integer.
Scanner in = new Scanner(System.in);
System.out.println("Eneter a nuber here:");
int num;
if (in.hasNextInt()){
num =in.nextInt();
if(num % 2 == 0){
System.out.print("this is even!!");
} else{
System.out.println("this is odd!!");
}
} else {
System.out.print("pleas enter an integer only!!!");
num = in.nextInt();
if(num % 2 == 0){
System.out.print("this is even second check!!");
} else{
System.out.println("this is odd second check!!");
}
}
here is the code but i have some mistakes in there. it brings an error when input is not an int. pleas help with this, thanks in advance!
Try the below code, it will end only if its a valid Integer otherwise it will keep asking for Integer and I think you are looking for the same.
public void checkInt() {
Scanner scanner = new Scanner(System.in);
System.out.println("Eneter a nuber here:");
try {
int num = scanner.nextInt();
if (num % 2 == 0) {
System.out.print("this is even!!");
} else {
System.out.println("this is odd!!");
}
} catch (InputMismatchException e) {
System.out.println("pleas enter an integer only!!!");
checkInt();
}
}
You must read user input as String. Then, inside a try/catch block, make a casting to integer (Integer.parseInt()), if throws a exception is because is not a number.
May be a stupid way but this can solve your problem:
String x;
x = "5";//or get it from user
int y;
try{
y = Integer.parseInt(x);
System.out.println("INTEGER");
}catch(NumberFormatException ex){
System.out.println("NOT INTEGER");
}
Edited:
The program will try to convert the string to integer. If it is integer it will succeed else it will get exception and be caught.
Another way is to check the ASCII value.
To continue till integer is encountered:
String x;
Scanner sc = new Scanner(System.in);
boolean notOk;
do{
x = sc.next();
notOk = check(x);
}while(notOk);
System.out.println("Integer found");
}
private static boolean check(String x){
int y;
try{
y = Integer.parseInt(x);
return false;
}catch(NumberFormatException ex){
return true;
}
}
import java.util.Scanner;
public class Test {
public static void main(String args[] ) throws Exception {
Scanner sc=new Scanner(System.in);
if(sc.hasNextInt())
System.out.println("Input is of int type");
else
System.out.println("This is something else");
}
}
I'm wondering if there is a way that I can make my code stricter with regard to user input?
I'm trying Exceptions / Try-Catch Blocks, and have to accept some user input and validate that it is the correct date type.
Is there a way that I can make the user input a strict double? i.e. I don't want the user to be able to input a value without a decimal point e.g. an int like 5 & have it be validated and converted to double, returning 5.0 - I want the user to be prompted to enter a double value strictly, making sure that a decimal point is part of the value entered.
Would using Wrappers or something like this be appropriate, and if so - how could I do this?
Current Code:
import java.util.Scanner;
public class InputExceptions {
//Do we have to do any Wrapping / instanceOf Double ?
//Can we accept an integer (no decimal point) for double entry ?
private static int inputInt;
private static double inputDouble;
public static int inputInt() {
Scanner kybd = new Scanner(System.in);
boolean inputOK = false;
while (inputOK == false) {
System.out.println("*** Please Enter an Integer Value: ");
try {
inputInt = kybd.nextInt();
kybd.nextLine();
inputOK = true;
} catch (Exception e) {
System.out.println("*** ERROR: VALUE ENTERED NOT INTEGER ***");
kybd.next();
}
}
return inputInt;
}
public static double inputDouble() {
Scanner kybd = new Scanner(System.in);
boolean inputOK = false;
while (inputOK == false) {
System.out.println("*** Please Enter a Double Value: ");
try {
inputDouble = kybd.nextDouble();
kybd.nextLine();
inputOK = true;
} catch (Exception e) {
System.out.println("*** ERROR: VALUE ENTERED NOT DOUBLE ***");
kybd.next();
}
}
return inputDouble;
}
public static void main(String[] args) {
System.out.println("*** INTEGER Input: " + inputInt() + " ***");
System.out.println("*** DOUBLE Input: " + inputDouble() + " ***");
}
}
You can read the number as a String and check it contains a '.' character. This can be parsed with Double.parseDouble(String). Of course you can still enter 1.0 and is the same as entering 1. or 1