This question already has answers here:
Scanner close after use
(2 answers)
Closed 3 years ago.
When I run my code, it will run fine up to the line "scanner.close()".
After than, when I run the "SumTenNumbers()" method... it will run the first line of the while loop once and crash with the "NoSuchElementException"...
When I remove the code above the line calling the method, it runs fine...
Why does this occur, and how can I solve it?
This is the code:
public class Main
{
public static void main(String[] args)
{
// we use the class "scanner" for input data
Scanner scanner = new Scanner(System.in); //System.in allows you to type input data into the console which can be returned into the console
System.out.println("Enter your name: ");
String name = scanner.nextLine();
System.out.println("Your name is " + name);
System.out.println("Enter your year of birth: ");
boolean isInt = scanner.hasNextInt();
if (isInt)
{
int yearOfBirth = scanner.nextInt();
int age = 2019 - yearOfBirth;
if (age >= 0 && age <= 120)
{
System.out.println("You are " + age + " years old");
}
else
{
System.out.println("Invalid year of birth");
}
}
else
{
System.out.println("Unable to parse year of birth");
}
scanner.close(); // we must close scanner
SumTenNumbers();
}
public static void SumTenNumbers()
{
var reader = new Scanner(System.in);
int sum = 0;
int count = 1;
while (count < 11)
{
System.out.println("Enter number " + count + ": ");
boolean valid = reader.hasNextInt();
if (valid)
{
int userNum = reader.nextInt();
sum += userNum;
count++;
}
else
{
reader.next();
System.out.println("INVALID");
}
}
System.out.println(sum);
reader.close();
}
}
This is how it looks when I run the code...
Enter your name:
Siddharth
Your name is Siddharth
Enter your year of birth:
2001
You are 18 years old
Enter number 1:
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 com.company.Main.SumTenNumbers(Main.java:64)
at com.company.Main.main(Main.java:39)
Process finished with exit code 1
the line reader.close() closes the Scanner and, with it, System.in.
After that, you cannot read from stdin (System.in) anymore.
In order to prevent this you can:
use only one Scanner object and close it after using it the last time
close System.in after using it the last time (using a Scanner or System.in.close())
close System.in at the end of your Program
never close System.in (Problem: other Processes cannot use the resource, stdin can also be a File, a Network Connection or something else)
Related
This question already has answers here:
How to handle infinite loop caused by invalid input (InputMismatchException) using Scanner
(5 answers)
java.util.NoSuchElementException - Scanner reading user input
(5 answers)
Closed 19 days ago.
I'm new to Java, just started a couple days ago. I have this program wich does some cool checks on an input number, but for semplicity i just created a class TestToFixLoopIssue because loop is actually the issue im facing. When we choose to enter a number, we enter the if with choice == 1, so the Test class is called, does its things, and when we quit that "program" we get an infinite loop in the console. This does not happen if i just copy paste the Test code into the if (removing its Scanner). So i think its a problem related to the multiple Scanners, but i dont know how to fix it.
EDIT: i tryed adding s.next(); but this does not fix the issue, it just gives another error in console wich stops the program:
Exception in thread "main" java.util.NoSuchElementException
public class Program {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
boolean exit = false;
while (!exit) {
System.out.println("What do you want to do?");
System.out.println("1. Check a number");
System.out.println("2. What is this program about?");
System.out.println("3. Quit");
if (s.hasNextInt()) {
int choice = s.nextInt();
s.nextLine();
if (choice == 1) {
System.out.println(" ");
// NumberChecker nc1 = new NumberChecker();
// nc1.check();
TestToFixLoopIssue test1 = new TestToFixLoopIssue();
test1.check();
} else if (choice == 2) {
System.out.println(" ");
System.out.println("This program checks multiple properties of a number.");
} else if (choice == 3) {
exit = true;
System.out.println(" ");
System.out.println("Program closed!");
} else {
System.out.println(" ");
System.out.println("Invalid choice. Try again.");
}
} else {
System.out.println("Invalid input. Try again.");
}
}
s.close();
}
}
public class TestToFixLoopIssue {
public void check() {
Scanner scan = new Scanner(System.in);
boolean repeat = true;
while (repeat) {
System.out.print("Insert a number: ");
int number = scan.nextInt();
System.out.println(" ");
System.out.println("You inserted " + number);
System.out.println("Do you want to check another number?");
System.out.println("1. Yes");
System.out.println("2. No");
if (scan.nextInt() == 2) {
repeat = false;
}
}
scan.close();
}
}
I dont want the loop to generate, so the user can keep using the program. I tryed some methods of the Scanner but neither of them worked, i dont actually know whats the issue exacty, so... help!
This question already has answers here:
How to use java.util.Scanner to correctly read user input from System.in and act on it?
(1 answer)
Java.util.scanner error handling
(2 answers)
Closed 1 year ago.
I need to write code where the program fails and throws an exception if the second input on a line is a String rather than an Integer. I am confused as to how to compare if the input is a string or an int and I am also struggling on how to use a try/catch statement.
import java.util.Scanner;
import java.util.InputMismatchException;
public class NameAgeChecker {
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
String inputName;
int age;
inputName = scnr.next();
while (!inputName.equals("-1")) {
// FIXME: The following line will throw an InputMismatchException.
// Insert a try/catch statement to catch the exception.
age = scnr.nextInt();
System.out.println(inputName + " " + (age + 1));
inputName = scnr.next();
}
}
Instead of
age = scnr.nextInt();
Try
try {
age = scnr.nextInt();
System.out.println(inputName + " " + (age + 1));
}
catch(InputMismatchException e) {
System.out.println("Please enter a valid integer");
}
I made a simple program which generates a random number between 1 to 100 and asks the user to enter a number between 1 and 100. If the number is more than the random number a message is displayed saying that it is more than the random number and if it is less it displays the opposite. The user only has 10 chances to guess the correct number. Here is the code:
import java.util.Scanner;
public class Program {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int random_num = (int) (Math.random() * 100) + 1;
System.out.println("guess a number between 1 and 100");
boolean isCorrect = false;
for (int i = 1; i <= 10; i++) {
int input = sc.nextInt();
if (input > random_num)
System.out.println("It is less than " + input);
else if (input < random_num)
System.out.println("It is more than " + input);
else {
isCorrect = true;
break;
}
}
if (isCorrect)
System.out.println("Congragulation you have guessd the correct number i.e " + random_num);
else
System.out.println("Game over it was " + random_num);
}
}
But I get errors here is the output:
guess a number between 1 and 100
It is more than 10
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: 1594)
at java.base/ java.util.Scanner.nextInt(Scanner.java: 2258)
at java.base/ java.util.Scanner.nextInt(Scanner.java: 2212)
at Program.main(Program.java:15)
You are looping over the Scanner, but not checking if you have any input to fetch.
Here is an excerpt from the Java docs:
public int nextInt()
Scans the next token of the input as an int.
An invocation of this method of the form nextInt() behaves in exactly the same way as the invocation nextInt(radix), where radix is the default radix of this scanner.
Returns:
the int scanned from the input
Throws:
InputMismatchException - if the next token does not match the Integer regular expression,
or is out of range
NoSuchElementException - if input is exhausted
IllegalStateException - if this scanner is closed
Spot your error message ;)
Your code is valid for a standard Java environment.
However since you run the code in the SoloLearn Java container, you run into an error case that normally shouldn't happen.
Which is another thread already closed the input stream.
As Ivar already mentioned, you simply need to change your code to this to make it work on SoloLearn without errors:
for (int i = 1; i <= 10 && sc.hasNextInt(); i++) {
// Your logic
}
But since SoloLearn's implementation needs you to feed all of your input at once (different inputs seperated by a line break), you won't be able to run this correctly with different guesses.
SoloLearn will take those inputs, seperated by line breaks, and reads the different lines one at a time.
Then returns the inputs one at a time to your program.
Once it has no more input, it will close the stream.
However your program still tries to read this stream and then gets a java.util.NoSuchElementException error.
Here is reproducable code of the error with wath I believe happens behind the scenes at SoloLearn:
import java.io.ByteArrayInputStream;
import java.util.Scanner;
public class Program {
private String[] userInput;
private int inputNumber;
public Program(String input) {
this.userInput = input.split(" ");
this.inputNumber = 0;
}
public void startGame() {
int random_num = (int)(Math.random()*100)+1;
System.out.println("Guess the number between 1 and 100!");
boolean isCorrect = false;
for (int i = 1; i <= 10; i++) {
System.out.print("Guess "+ i +": ");
int input = getInput();
if (input > random_num)
System.out.println("It is less than " + input);
else if (input < random_num)
System.out.println("It is more than " + input);
else {
isCorrect = true;
break;
}
}
if(isCorrect)
System.out.println("Congratulations, you have guessed the correct number i.e " + random_num);
else
System.out.println("Game over! The number was " + random_num);
}
private int getInput() {
if (inputNumber < userInput.length)
fakeUserInput();
Scanner sc = new Scanner(System.in);
int input = -1;
input = sc.nextInt();
if (inputNumber == userInput.length)
sc.close();
return input;
}
private void fakeUserInput() {
System.setIn(new ByteArrayInputStream(userInput[inputNumber].getBytes()));
inputNumber++;
}
public static void main(String[] args) {
Program p = new Program("10 20 30");
p.startGame();
}
}
We feed it 3 guesses: 10, 20 and 30
And this is the output:
Guess the number between 1 and 100!
Guess 1: It is more than 10
Guess 2: It is more than 20
Guess 3: It is more than 30
Guess 4: Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:873)
at java.util.Scanner.next(Scanner.java:1496)
at java.util.Scanner.nextInt(Scanner.java:2128)
at java.util.Scanner.nextInt(Scanner.java:2087)
at Program.getInput(Program.java:47)
at Program.startGame(Program.java:24)
at Program.main(Program.java:62)
As you can see, once the inputs are depleted and the stream is closed, we get this error.
I hope this explains your problem and sheds some light on the WHY.
here is answer, I try to do it and I found in main sc.close(). After comment line all work nice! :
#I_code Is this the actual code you are using? It works fine for me. That error is thrown when the the System.in is closed. Are you using sc.close() somewhere that you didn't show in the code?
– #Ivar Mar 15 '19 at 10:10
Good morning you need to initialize the input variable outside the for like this:
int input;
for (int i = 1; i <= 10; i++) {
input = sc.nextInt();
if (input > random_num)
Try this and tell me
I am new to java programming, and i am trying to learn about different methods available in Scanner class, i came to hasNextInt(); method,does this method has any default values,either true or false,since in the code, first compiler prints "Enter your year of birth:",then compiler moves to next Line that is , boolean hasNextInt = scanner.hasNextInt();,at this point what compiler will do since it has no input?.
This code is working fine,for example if i give invalid input to yearOfBirth ,like "abc" it prints "Unable to parse year of birth.",and when i give valid integer input it works fine too.
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter your year of birth:");
boolean hasNextInt = scanner.hasNextInt();
if(hasNextInt) {
int yearOfBirth = scanner.nextInt();
scanner.nextLine(); // handle next line character (enter key)
System.out.println("Enter your name: ");
String name = scanner.nextLine();
int age = 2018 - yearOfBirth;
if(age >= 0 && age <= 100) {
System.out.println("Your name is " + name + ", and you are " + age + " years old.");
} else {
System.out.println("Invalid year of birth");
}
} else {
System.out.println("Unable to parse year of birth.");
}
scanner.close();
}
To quote the Javadoc:
Both hasNext and next methods may block waiting for further input. Whether a hasNext method blocks has no connection to whether or not its associated next method will block.
In other words, the hasNextInt method will block (wait) if necessary until input is received.
This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 7 years ago.
Whenever I run the program, everything works fine but for some reason the Confirmation prints are happening twice and I can't figure out why. Any help would be appreciated.
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String Z = "Z";
int number;
String Znumber = "";
String Confirmation = "";
int ExamType;
// Ask user for Z number
do {
System.out.println("Please enter your Z number. Example: 12345678");
number = input.nextInt();
Znumber = Z + number;
} while ((Znumber.length() != 9));
//Confirm Z number entry
do {
System.out.printf(
"Your Z number is: %s. Is this correct? Enter Y/N: \n",
Znumber);
Confirmation = input.nextLine();
} while (!Confirmation.equalsIgnoreCase("y"));
// Ask user which exam they would like to take
ExamType = 0;
Confirmation = "";
System.out.println("Which exam would you like to take? Select 1-3: ");
System.out.println("1: English");
System.out.println("2: Spanish");
System.out.println("3: Math");
ExamType = input.nextInt();
do {
System.out.printf("You selected %s. Are you sure? Enter Y/N: \n",
ExamType);
Confirmation = input.nextLine();
} while (!Confirmation.equalsIgnoreCase("y"));
// Begin exam
if (ExamType == 1) {
System.out.println("Welcome to the English exam!");
// Start code from JavaExam.java
} else if (ExamType == 2) {
System.out.println("Welcome to the Spanish exam!");
// Start code from MathExam.java
} else if (ExamType == 3) {
System.out.println("Welcome to the Math exam!");
// Start code from EnglishExam.java
Instead of Confirmation = input.nextLine();, use Confirmation = input.next(); and you should be good. Tested and confirmed.
You really don't need nextLine here in your do-while loop.
Your first loop (// Ask user for Z number)
number = input.nextInt();
does not read the last '\n'.
I think you need to add a nextLine() in that loop.
In your do-while when you run for the first time print Your Z number is: %s. Is this correct? Enter Y/N:. after that the condition !Confirmation.equalsIgnoreCase("y") is evaluated in this case gives true for this cause try to run the loop do-while in second time.
do {
System.out.printf("Your Z number is: %s. Is this correct? Enter Y/N: \n",
....
} while (!Confirmation.equalsIgnoreCase("y"));