this error seems to be a very common issue. I've looked up on other Stack Overflow posts that ask about this and tried to implement their solutions, but I'm still getting the same error. The complete error is:
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 src.file.main(file.java:29)
I'm sure there's something really simple I'm missing, but I can't quite find it as when I read through my code, the logic seems good. This is my file:
public class file {
public static void main(String[] args) throws IOException {
int choice = 0;
Scanner myVal = new Scanner(System.in);
while(choice != 3) {
System.out.println("1. enter info \n2. print info \n3.exit");
System.out.println("Enter a choice: ");
choice = myVal.nextInt(); //Line 29
if(choice == 1) {
enterInfo();
}
else if(choice == 2) {
print();
}
else if(choice == 3) {
System.exit(0);
}
}
}
static ArrayList<newType> studInfo = new ArrayList<src.newType>();
static void enterInfo() {
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter the information (Program year average lastname): ");
String info = keyboard.nextLine().trim();
if(info.isEmpty()) {
System.out.println("Error, no input was made.");
keyboard.close();
return;
}
String[] tokens = info.split(" ");
int size = tokens.length;
String prgm = tokens[0];
int yr = Integer.parseInt(tokens[1]);
String lastname = tokens[3];
Double avg = Double.parseDouble(tokens[2]);
newType inf = new newType(prgm, yr, avg, lastname);
studInfo.add(inf);
System.out.println("Information added.");
keyboard.close();
return;
}
Example input: math 5 76 Smith, this information is added to the arraylist of type newType where it can be printed, or another profile can be added.
The program compiles without errors or warnings, and I can successfully run the program. When I choose option 1, I enter all the information, in the correct format, to which I get the information added message, signaling it was a successful process. After this message, the exception appears. This leads me to believe the error doesn't actually lie within my enterInfo function, as I first thought, but rather when it reaches line 29 for the second time. I don't know how to fix this error, could anyone help? Thanks in advance!
Apart from the mistakes done in using Scanner, the standards followed in java is also missing.
Classname should start with caps (file should be as File, same with newType as well. It should be NewType)
If you are naming any class then it should be a noun and so should be named as per the goal to be achieved in the program such as AddingNumbers, ReverseNumbers.
Pls refer here why we shouldn't use multiple scanner in a program : Why does closing a scanner seem to break new scanners?
I have made few changes in your code.Hope this works !!!
// modified code
public class File {
static Scanner myVal = new Scanner(System.in); // Use this scanner throughout the program
static ArrayList<newType> studInfo = new ArrayList<src.newType>();
public static void main(String[] args) throws IOException {
int choice = 0;
while (choice != 3) {
System.out.println("1. enter info \n2. print info \n3.exit");
System.out.println("Enter a choice: ");
choice = myVal.nextInt(); // Line 29
if (choice == 1) {
enterInfo();
} else if (choice == 2) {
// print();
} else if (choice == 3) {
System.exit(0);
}
}
myVal.close(); // Can be closed once the need is over.
}
static void enterInfo() {
// Scanner keyboard = new Scanner(System.in); No need of multiple scanners.
System.out.println("Enter the information (Program year average lastname): ");
String info = myVal.nextLine().trim();
if (info.isEmpty()) {
System.out.println("Error, no input was made.");
// keyboard.close();
return;
}
String[] tokens = info.split(" ");
int size = tokens.length;
String prgm = tokens[0];
int yr = Integer.parseInt(tokens[1]);
String lastname = tokens[3];
Double avg = Double.parseDouble(tokens[2]);
newType inf = new newType(prgm, yr, avg, lastname);
studInfo.add(inf);
System.out.println("Information added.");
// keyboard.close();
return;
}
}
Related
I am getting a NoSuchElementException which is probably due to Scanner and I get it after I add a student and go back to the menu.
My main method:
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
static ArrayList<Student> students = new ArrayList<>();
static Scanner scan = new Scanner(System.in);
static Student s = new Student();
public static void main(String[] args) {
menu();
}
public static void menu() {
System.out.println(" ***Students Manage***\n");
System.out.println("1 - Insert a student");
System.out.println("2 - Display students");
System.out.println("3 - Remove student\n");
option();
}
public static void option() {
int option;
do {
System.out.print("Choose an option: ");
option = scan.nextInt();
}while(option < 1 || option > 3);
switch(option) {
case 1:
s.addStudent();
students.add(s);
break;
case 2:
showAllStudents();
}
menu();
}
private static void showAllStudents() {
for(int i = 0; i < students.size(); i++) {
students.get(i).toString();
}
}
}
My Student method:
import java.time.LocalDate;
import java.util.Scanner;
public class Student {
String name;
int studentNumber;
static int count = 1;
int yearNumber;
public Student() {
}
public void addStudent() {
Scanner scan = new Scanner(System.in);
LocalDate year = LocalDate.now();
yearNumber = year.getYear();
studentNumber = count++;
studentNumber += yearNumber * 10000;
System.out.print("Enter the student name: ");
name = scan.nextLine();
if(name == null || name.trim().equals("") || !name.contains(" "))
{
do{
if(name.trim().equals("")){
System.out.print("Please enter a valid name.\nEnter your name: ");
} else if(!name.contains(" ")) {
System.out.print("You should write at least 2 names(name and surname).\nEnter your name: ");
}
name = scan.nextLine();
}while(name == null || name.trim().equals("") || !name.contains(" "));
}
scan.close();
System.out.println("The student "+name+" was added to the student list "
+ "and his/her student number is "+studentNumber);
}
#Override
public String toString(){
return name+" - "+studentNumber;
}
}
The error that I'm getting:
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 StudentSchool.Main.option(Main.java:29)
at StudentSchool.Main.menu(Main.java:21)
at StudentSchool.Main.option(Main.java:40)
at StudentSchool.Main.menu(Main.java:21)
at StudentSchool.Main.option(Main.java:40)
at StudentSchool.Main.menu(Main.java:21)
at StudentSchool.Main.main(Main.java:13)
You have two problems in how you're using Scanner. The first is that you are opening a second Scanner on System.in while you have one already open and reading from it. This produces strange results due to buffering. You should create and use only a single Scanner object that you never close. You can do this by passing the Scanner you create in your main() method into your addStudent() method so that it can use that same Scanner instead of creating and later closing a new one. So...
public void addStudent(Scanner scan) {
// Scanner scan = new Scanner(System.in);
....
// scan.close();
....
public static void option() {
....
s.addStudent(scan);
...
When you do this, a second problem will arise. When you mix calls to nextInt and nextLine on a Scanner object, you run into a problem where nextInt only reads the numeric digits from the input stream, but leaves the newline character produce by the user hitting Return. When you then call readLine, it reads that newline that's already on the input stream, so instead of waiting for your input, it reads an empty line as the next result. To avoid this problem, you should add an extra call to readLine right after you call readInt to consume this stray newline character. So...
System.out.print("Choose an option: ");
option = scan.nextInt();
scan.nextLine();
Making these two changes should cause your program to behave as you desire.
I'm newbie in Java and I'm trying to read data from keyboard but I'm getting an exception and I don't know why and how to fix it.
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Test r = new Test();
System.out.println("Type a int number : " + r.readInteger());
System.out.println("type a double number: " + r.readDouble());
}
public int readInteger() {
Scanner input = new Scanner(System.in);
int val = 0;
while(true) {
if(input.hasNextInt()) {
val = input.nextInt();
input.nextLine();
break;
}
else {
System.out.println("Invalid data type.");
input.nextLine();
}
}
input.close();
return val;
}
double readDouble() {
Scanner input = new Scanner(System.in);
double val = 0;
while(true) {
if(input.hasNextDouble()) {
val = input.nextDouble();
input.nextLine();
break;
}
else {
System.out.println("Invalid data type.");
input.nextLine();
}
}
input.close();
return val;
}
}
The excpetion:
[roger#archroger ~]$ java Test
3
Type a int number : 3
Invalid data type.
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1540)
at Test.readDouble(Test.java:44)
at Test.main(Test.java:8)
Don't close the scanner when it's input stream is System.in. This will close the standard input as well and statements like scanner.nextLine() will throw a NoSuchElementException when you do not check if the line is present. You check with scanner.hasNextInt() if another integer token is available and then try to get another line with scanner.getNextLine() without testing if this line exists at all. Use scanner.hasNextLine().
I have a problem with my restaurant assignment - I'm required to
Create a while loop with a required quantity that user purchases to be between 1 and 15. User has 3 attempts and if after the third time he doesn't put the right quantity 1
Using a do- while loop user has to answer if he wants to run a program again. If he answers 'Y' (for yes) it runs again, if the answer is 'N' (for no ) it terminates.
I keep getting errors: the while loop does only 2 attempts, and the do while doesn't work at all.
import java.text.DecimalFormat;
import java.util.Scanner;
public class newone {
public static void main (String[] args){
char repeat;
// To hold 'y' or 'n'
String input;
DecimalFormat df = new DecimalFormat("$0.00");
//to use: df.format(doubleVariable)
//Display any welcome message at the top of the output screen
System.out.println("Welcome!");
double price = 5.0;
System.out.println("Burger is " + df.format(price));
Scanner keyboard = new Scanner(System.in);
int attempts = 0;
int maxAttempts = 3;
int quantity;
System.out.print("Enter amount of burgers: ");
quantity = keyboard.nextInt();
//LESS THAN OR EQUAL TO 3...
while(quantity <1 || quantity >=15 && attempts<=maxAttempts){
if(quantity < 1 || quantity >= 15){
System.out.println("That is an invalid amount, please try again");
quantity= keyboard.nextInt();
++attempts;
}
else if(quantity>1 && quantity<15){
//user entered a valid amount
System.out.println("The amount is valid. You ordered: "+ quantity);
double subTotal = quantity * price;
}
while (attempts>=maxAttempts){
System.out.println("Too many attempts, you can't order");
break;
}
}
do{
System.out.println("Would you like to run the program again?");
System.out.print("Enter Y for yes or N for no: ");
input = keyboard.nextLine(); // Read a line.
repeat = input.charAt(0); // Get the first char.
}
//it gives me an error Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.String.charAt(Unknown Source)
while (repeat == 'Y' || repeat == 'y');
}
}}
Below line causes the error:
repeat = input.charAt(0);
Perhaps user is not providing any inputs (i.e. user just hits enter when program asks for any input) and hence, string doesn't have any character. Extracting first character from blank string throws this error.
The solution will be to check for empty string (using length() method) before executing charAt(0).
You have lots of problems here.
Here's how I'd do it. It's never too early to learn about decomposition and writing clean, readable code:
/**
* Created by Michael
* Creation date 3/4/2016.
* #link https://stackoverflow.com/questions/35806509/java-while-do-while-loop-with-users-decision-to-run-program-again/35806638?noredirect=1#comment59284245_35806638
*/
import java.text.NumberFormat;
import java.util.Scanner;
public class BurgerKing {
public static final int MAX_ATTEMPTS = 3;
public static final int MIN_QUANTITY = 1;
public static final int MAX_QUANTITY = 15;
public static final NumberFormat PRICE_FORMAT = NumberFormat.getCurrencyInstance();
public static void main (String[] args){
Scanner keyboard = new Scanner(System.in);
String answer;
do {
System.out.println("Welcome! Please place your order");
int quantity = getBurgerQuantity(keyboard);
double price = getBurgerPrice(keyboard);
System.out.println(String.format("Your total is: %s", PRICE_FORMAT.format(quantity*price)));
System.out.print("Another order? [Y/N]: ");
answer = keyboard.nextLine();
} while ("Y".equalsIgnoreCase(answer));
}
public static boolean isValidQuantity(int quantity) {
return (quantity >= MIN_QUANTITY && quantity =< MAX_QUANTITY);
}
public static int getBurgerQuantity(Scanner scanner) {
int numBurgers;
int attempts = 0;
do {
System.out.print("How many burgers would you like? ");
numBurgers = Integer.parseInt(scanner.nextLine());
} while (!isValidQuantity(numBurgers) && (++attempts < MAX_ATTEMPTS));
if (attempts == MAX_ATTEMPTS) throw new IllegalArgumentException(String.format("%d attempts is too many", attempts));
return numBurgers;
}
public static double getBurgerPrice(Scanner scanner) {
String price;
System.out.print("Name your burger price: ");
price = scanner.nextLine();
return Double.parseDouble(price);
}
}
The bufferedreader I have used in my code seems to read only the first line of the code. Can some one help me solve the problem, I've been trying for a long time.
import java.util.Scanner;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.BufferedReader;
public class Task2Recipe {
private static String Ingredient;
private static String ServingNumber;
public static void main(String[] args) {
Scanner user_input = new Scanner(System.in);
System.out.println("Hello. If you would like to write a new recipe, please type in 'write', if you would like to change and view a recipe, please type in 'read'");
String choice = user_input.next();
user_input.nextLine();
if (choice.equals("write")) {
write();
}
if (choice.equals("read")) {
read();
}
}
public static void write() {
try {
FileWriter Task2Recipe = new FileWriter("P:/Year 11/GCSE Computing/A453/Task 2/Recipe.txt");
BufferedWriter recipe = new BufferedWriter(Task2Recipe);
Scanner user_input = new Scanner(System.in);
System.out.println("Please enter the name of your recipe, if more than 1 word, seperate your words with a dash");
String RecipeName = user_input.next();
recipe.write("Name of recipe: " + RecipeName);
recipe.newLine();
System.out.println("Please enter the number of people your recipe serves");
ServingNumber = user_input.next();
recipe.write(ServingNumber);
recipe.newLine();
System.out.println("Please enter the name of your first ingredient, the quantity and units separated with a comma");
Ingredient = user_input.next();
recipe.write(Ingredient);
recipe.newLine();
System.out.println("Do you want to enter another ingredient? yes/no? Please type in either in lower case");
String choice2 = user_input.next();
user_input.nextLine();
while (choice2.equals("yes")) {
System.out.println("Please enter the name of your ingredient, the quantity and units separated with a comma");
Ingredient = user_input.nextLine();
recipe.write(Ingredient);
System.out.println("Do you want to enter another ingredient? yes/no? Please type in either in lower case");
choice2 = user_input.next();
user_input.nextLine();
}
recipe.close();
} catch (Exception e) {
System.out.println("A write error has occured");
}
}
public static void read() {
try {
Scanner user_input = new Scanner(System.in);
FileReader file = new FileReader("P:Year 11/GCSE Computing/A453/Task 2/Recipe.txt");
BufferedReader buffer = new BufferedReader(file);
System.out.println("Would you like to change the serving number of your recipe, type in 'yes' to proceed, type in 'no'");
String choice3 = user_input.next();
user_input.nextLine();
while (choice3.equals("yes")) {
String line;
System.out.println("Please enter the new serving number");
int NewServingNumber = user_input.nextInt();
int counter = 0;
while ((line = buffer.readLine()) != null) {
counter++;
if (counter == 2) {
}
if (counter > 3) {
String[] word = Ingredient.split(",");
int Quantity = Integer.parseInt(word[1]);
int ServingNumberInt = Integer.parseInt(ServingNumber);
int Multiplier = ServingNumberInt / Quantity;
int NewQuantity = (Multiplier * NewServingNumber);
System.out.println("Your new quantity is " + NewQuantity);
}
}
System.out.println(line);
buffer.close();
}
} catch (Exception e) {
System.out.println("A read error has occured");
}
}
}
My input was:
applep - for the recipe name
10 - for serving number
apple,10,apples - for the ingredient, I only added 1 ingredient.
When I read and read my file and change the recipe servinging number, it doesn't not work and gives in an 'read error'. In addition, to test the problem, I printed the variable 'line' and it only seems to read the first line.
Thanks in advance!
You have two independent cases - one for reading and one for writing. If in one case, you assign values to variables, it does not mean that in other case you can read them. Also the counter is not set correctly. Try this code -
while((line = buffer.readLine()) !=null) {
counter++;
if (counter == 3) {
//String[]word = Ingredient.split(",");
String[]word = line.split(",");
int Quantity = Integer.parseInt(word[1]);
//int ServingNumberInt = Integer.parseInt();
int Multiplier = NewServingNumber / Quantity;
int NewQuantity = (Multiplier * NewServingNumber);
System.out.println("Your new quantity is " + NewQuantity);
}
}
it gives -
Hello. If you would like to write a new recipe, please type in 'write', if you would like to change and view a recipe, please type in 'read'
read
Would you like to change the serving number of your recipe, type in 'yes' to proceed, type in 'no'
yes
Please enter the new serving number
10
Your new quantity is 10
I don't understand the logic to this. If I run this code and enter a non-int such as the letter f, I get stuck in an infinite loop outputting the two println's and I am not given another chance to input an int to the scanner...it just keeps spitting out words to the console.
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);//<<<<<SCANNER HERE
int opponents = 0;
boolean opponentsCreated = false;
while(opponentsCreated == false)
{
try
{
System.out.print("How many players: ");
int tempOpponents = scan.nextInt();
if(tempOpponents > 0)
{
opponents = tempOpponents;
opponentsCreated = true;
}
}
catch(InputMismatchException notAValidInt)
{
System.out.println("Not valid - must be a number greater than 0 ");
}
}
}
But if I simply change the Scanner to be declared inside the while loop, all of a sudden the program works as expected:
public static void main(String[] args) {
int opponents = 0;
boolean opponentsCreated = false;
while(opponentsCreated == false)
{
Scanner scan = new Scanner(System.in);//<<<<<SCANNER HERE
try
{
System.out.print("How many players: ");
int tempOpponents = scan.nextInt();
if(tempOpponents > 0)
{
opponents = tempOpponents;
opponentsCreated = true;
}
}
catch(InputMismatchException notAValidInt)
{
System.out.println("Not valid - must be a number greater than 0 ");
}
}
}
I honestly just sat here for 2 hours trying to figure out what the heck was wrong with my program only to find out it was a matter of where I declared my Scanner even though in both versions of the code the Scanner was not out of scope. So now I'm really curious why it works this way
Adding on to #HovercraftFullOfEels answer:
The root cause is, the scanner position does not move in case of the said exception. So scanner keeps reating same bad input again and again. Quoting JavaDoc
If the translation is successful, the scanner advances past the input
that matched.
catch(InputMismatchException notAValidInt)
{
scan.reset();
System.out.println("Not valid - must be a number greater than 0 ");
//position is still 0
scan.next(); //position is now 1
}
To visualize:
Input: f______________
Scanner position: ^______________
InputMismatchException ^______________
scan.next() _^_____________
Relevant source (look at the source comment):
try {
String s = next(integerPattern());
if (matcher.group(SIMPLE_GROUP_INDEX) == null)
s = processIntegerToken(s);
return Integer.parseInt(s, radix);
} catch (NumberFormatException nfe) {
position = matcher.start(); // don't skip bad token
throw new InputMismatchException(nfe.getMessage());
}
One possible problem is that you may be leaving the end of line token hanging when an excpetion occurs. If you handle this by making sure to swallow the end of line token when needed, you are likely OK. For example:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);// <<<<<SCANNER HERE
int opponents = 0;
boolean opponentsCreated = false;
while (opponentsCreated == false) {
try {
System.out.print("How many players: ");
int tempOpponents = scan.nextInt();
// line below corrected!
scan.nextLine(); // *** this might not be a bad idea either ***
if (tempOpponents > 0) {
opponents = tempOpponents;
opponentsCreated = true;
}
} catch (InputMismatchException notAValidInt) {
System.out.println("Not valid - must be a number greater than 0 ");
scan.nextLine(); // ****** this is what you need here *****
}
}
}
Nice question, by the way!