Java scanner nextint loop

Using Scanner inside a for loop for system input

I have been struggling with this for a while. I essentially want to loop through and read in as many strings as determined by num_choices . The following code only executes the else condition.

 Scanner s2 = new Scanner(System.in); for(int i=0; i < this.num_choices; i++) < if(s2.hasNext()) < System.out.println("Enter choice " + (i+1) +":"); String ch = s2.next(); //this.choices.addElement(ch); >else < System.out.println("Lets end this"); >> 

` I am getting this: Exception in thread «main» java.util.NoSuchElementException . In the main class, this is where the error points to

 choice2 = Integer.parseInt(read_choice2.next()); 
public class Main < public static void main(String args[]) throws IOException < Vectormysurveys = new Vector(); boolean carry_on = true; int choice = 0; Scanner read_choice = new Scanner(System.in); System.out.println("Let's begin the Survey/Test application!"); while(carry_on) < System.out.println("What would you like to do?"); System.out.println("1. Create a new Survey"); System.out.println("2. Create a new Test"); System.out.println("3. Display a Survey"); System.out.println("4. Display a Test"); System.out.println("5. Save a Survey"); System.out.println("6. Save a Test"); System.out.println("7. Load a Survey"); System.out.println("8. Load a Test"); System.out.println("9. Quit"); System.out.println(); System.out.println("Please enter a number for the operation you want to perform: "); choice = Integer.parseInt(read_choice.next()); /*try < choice = Integer.parseInt(buffer.readLine()); >catch(InputMismatchException e) < System.out.println("Invalid input. Please Enter again."); System.out.println(); //read_choice.nextInt(); >*/ switch(choice) < case 1: System.out.println("Please Enter a Name for your Survey"); String in = buffer.readLine(); Survey s1 = new Survey(); s1.CreateNew(in); mysurveys.add(s1); //// add_question(s1.type); break; case 2: System.out.println("Please Enter a Name for your Test"); //String in = buffer.readLine(); Test t1 = new Test(); //t1.CreateNew(in); mysurveys.add(t1); break; //// //add_question(t1.type); case 3: break; // call Survey.display() case 4: break; case 5: Survey s = new Survey(); ReadWriteFiles x = new ReadWriteFiles(); x.SaveSurvey(s); break; case 6: Test t = new Test(); //ReadWriteFiles x = new ReadWriteFiles(); //x.SaveSurvey(t); break; case 7: carry_on = false; break; default: System.out.println("Incorrect Input. Try Again"); System.out.println(); break; >> read_choice.close(); > public static void add_question(String type) throws IOException, NullPointerException < Questions q = null; boolean carry_on2 = true; int choice2 = 0; Scanner read_choice2 = new Scanner(System.in); //BufferedReader buffer2=new BufferedReader(new InputStreamReader(System.in)); while (carry_on2) < // System.out.println("1. Add a new T/F Question"); System.out.println("2. Add a new Multiple Choice Question"); System.out.println("3. Add a new Short Answer Question"); System.out.println("4. Add a new Essay Question"); System.out.println("5. Add a new Ranking Question"); System.out.println("6. Add a new Matching Question"); System.out.println("7. If you want to stop adding more questions, and go back to the main menu."); System.out.println("Please enter a number for the operation you want to perform: "); choice2 = Integer.parseInt(read_choice2.next()); /*try < choice2 = Integer.parseInt(buffer2.readLine()); >catch(InputMismatchException e) < System.out.println("Invalid input. Please Enter again."); System.out.println(); //read_choice2.nextInt(); >*/ switch(choice2) < case 1: q = new TrueFalse(); break; case 2: q = new MultipleChoice(); break; case 3: q = new ShortAnswer(); break; case 4: q = new Essay(); break; case 5: q = new Ranking(); break; case 6: q = new Matching(); break; case 7: carry_on2 = false; break; default: System.out.println("Incorrect Input."); break; >q.createQuestion(type); > > > 

I realize there is a lot of messy code, and I apologize for that. I just wanted to show the entire thing, so it’s easier to spot the problem. Help would be appreciated.

Источник

Java: Infinite loop using Scanner in.hasNextInt()

However, if I enter a ‘w’ it will tell me «You have entered invalid input. Try Again.» and then it will go into an infinite loop showing the text «Specify an integer between 0 and 5: You have entered an invalid input. Try again.» Why is this happening? Isn’t the program supposed to wait for the user to input and press enter each time it reaches the statement:

Since you haven’t shown anybody what in is, or how you constructed it, there’s no telling how it should behave!

Читайте также:  Java get new class instance

4 Answers 4

In your last else block, you need to clear the ‘w’ or other invalid input from the Scanner. You can do this by calling next() on the Scanner and ignoring its return value to throw away that invalid input, as follows:

The problem was that you did not advance the Scanner past the problematic input. From hasNextInt() documentation:

Returns true if the next token in this scanner’s input can be interpreted as an int value in the default radix using the nextInt() method. The scanner does not advance past any input.

This is true of all hasNextXXX() methods: they return true or false , without advancing the Scanner .

Here’s a snippet to illustrate the problem:

 String input = "1 2 3 oops 4 5 6"; Scanner sc = new Scanner(input); while (sc.hasNext()) < if (sc.hasNextInt()) < int num = sc.nextInt(); System.out.println("Got " + num); >else < System.out.println("int, please!"); //sc.next(); // uncomment to fix! >> 

You will find that this program will go into an infinite loop, asking int, please! repeatedly.

If you uncomment the sc.next() statement, then it will make the Scanner go past the token that fails hasNextInt() . The program would then print:

Got 1 Got 2 Got 3 int, please! Got 4 Got 5 Got 6 

The fact that a failed hasNextXXX() check doesn’t skip the input is intentional: it allows you to perform additional checks on that token if necessary. Here’s an example to illustrate:

 String input = " 1 true foo 2 false bar 3 "; Scanner sc = new Scanner(input); while (sc.hasNext()) < if (sc.hasNextInt()) < System.out.println("(int) " + sc.nextInt()); >else if (sc.hasNextBoolean()) < System.out.println("(boolean) " + sc.nextBoolean()); >else < System.out.println(sc.next()); >> 

If you run this program, it will output the following:

(int) 1 (boolean) true foo (int) 2 (boolean) false bar (int) 3 

This statement by Ben S. about the non-blocking call is false:

Also, hasNextInt() does not block. It’s the non-blocking check to see if a future next call could get input without blocking.

. although I do recognize that the documentation can easily be misread to give this opinion, and the name itself implies it is to be used for this purpose. The relevant quote, with emphasis added:

The next() and hasNext() methods and their primitive-type companion methods (such as nextInt() and hasNextInt()) first skip any input that matches the delimiter pattern, and then attempt to return the next token. 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.

It is a subtle point, to be sure. Either saying «Both the hasNext and next methods», or «Both hasnext() and next()» would have implied that the companion methods would act differently. But seeing as they conform to the same naming convention (and the documentation, of course), it’s reasonable to expect they act the same, and hasNext() clearly says that it can block.

Meta note: this should probably be a comment to the incorrect post, but it seems that as a new user I can only post this answer (or edit the wiki which seems to be preferred for sytlistic changes, not those of substance).

Источник

Java Loop/User Input from Scanner

Making just a simple basketball program where I ask for the home team name, how many games are in the season, and then in a loop ask for the next team game. Basically when I start the do-while loop, it works great, unless the user types in for example, «Ohio State.» The out put will then go from «6 games remaining» to «4 games remaining» for example. Usually it will just ask opponent?, then decrement by one game. How can I fix so that a 2 word basketball team name doesn’t decrement twice?

import java.util.Scanner; public class Basketball2 < public static void main(String[] args) throws java.io.IOException < Scanner scanInput = new Scanner(System.in); String sHomeTeam; String sAwayTeam; int iNumGames; int iGamesLeft = 0; System.out.println("Enter home team's name: "); sHomeTeam = scanInput.nextLine(); System.out.println(sHomeTeam); System.out.println("How many games are in the home team's basketball season?"); iNumGames = scanInput.nextInt(); System.out.println(iNumGames); //start looping do < System.out.println("Enter opponent team's name: "); sAwayTeam = scanInput.next(); System.out.println(sAwayTeam); iGamesLeft = --iNumGames; System.out.println("There are " + iGamesLeft + " games left in the basketball season"); >//end do while(iGamesLeft > 0); 

4 Answers 4

Replace: sAwayTeam = scanInput.next(); with sAwayTeam = scanInput.nextLine(); The reason it loops twice is because scanInput.next(); only returns one token (e.g. word) at a time. When you enter two words it doesn’t need receive more input from the user before continuing a second time because it already has another word to return. Hence the double loop.

Читайте также:  String classes in java with example

You also need to take care of the line of code that calls nextInt() . This works like the next() method, but, instead of a token (word), it scans in just one character as an int. Try this: after iNumGames = scanInput.nextInt(); put scanInput.nextLine(); This should clear scanInput of anything that is making it skip. Note: because of the way that your code is written, this will only read one character. If you need to read more than one character you should use nextLine() and assign its value to an integer.

Источник

Java Scanner while loop

I’m trying to take in a string input which consists of multiple lines of numbers separated by ‘,’ and ‘;’ . Example:

ArrayList alist = new ArrayList<>(); String delims = ";|\\,"; int i = 0; Scanner input = new Scanner(System.in); input.useDelimiter(delims); while (input.hasNext()) < alist.add(i, input.nextInt()); System.out.print(i + ' '); System.out.print(alist.get(i) + '\n'); i++; >System.out.print('x'); 
0 1 1 2 2 3 3 4 4 5 5 6 x 

my use of Scanners hasNext() method has been when reading files; maybe you need a sentinel-controlled loop. Loop until the user enters -999 or some int that shouldn’t be part of the entered data

2 Answers 2

One problem is that System.in is basically an infinite stream: hasNext will always return true unless the user enters a special command that closes it.

So you need to have the user enter something that tells you they are done. For example:

while(input.hasNext()) < System.out.print("Enter an integer or 'end' to finish: "); String next = input.next(); if("end".equalsIgnoreCase(next)) < break; >int theInt = Integer.parseInt(next); . 

For your program, you might have the input you are trying to parse end with a special character like 1,2;3,4;5,6;end or 1,2;3,4;5,6;# that you check for.

System.out.print(i + ' '); System.out.print(alist.get(i) + '\n'); 

It looks like you are trying to perform String concatenation but since char is a numerical type, it performs addition instead. That is why you get the crazy output. So you need to use String instead of char :

System.out.print(i + " "); System.out.print(alist.get(i) + "\n"); 
System.out.println(i + " " + alist.get(i)); 

You could, for example, pull the input using nextLine from a Scanner with a default delimiter, then create a second Scanner to scan the line:

Scanner sysIn = new Scanner(System.in); while(sysIn.hasNextLine()) < String nextLine = sysIn.nextLine(); if(nextLine.isEmpty()) < break; >Scanner lineIn = new Scanner(nextLine); lineIn.useDelimiter(";|\\,"); while(lineIn.hasNextInt()) < int nextInt = lineIn.nextInt(); . >> 

oh man its always the little things, changing to the double speech completely fixed the output 🙂 thanks

Since Radiodef has already answered your actual problem( » instead of ‘ ), here are a few pointers I think could be helpful for you(This is more of a comment than an answer, but too long for an actual comment):

When you use Scanner, try to match the hasNextX function call to the nextX call. I.e. in your case, use hasNextInt and nextInt . This makes it much less likely that you will get an exception on unexpected input, while also making it easy to end input by just typing another delimiter.

Читайте также:  Disable error log in php

Scanners useDelimiter call returns the Scanner, so it can be chained, as part of the initialisation of the Scanner. I.e. you can just write:

Scanner input = new Scanner(System.in).useDelimiter(";|\\,"); 

When you add to the end of an ArrayList, you don’t need to(and usually should not) specify the index.

int i = 0 , i++ is the textbook example of a for loop. Just because your test statement doesn’t involve i does not mean you should not use a for loop.

Your code, with the above points addressed becomes as follows:

ArrayList alist = new ArrayList<>(); Scanner input = new Scanner(System.in).useDelimiter(";|\\,"); for (int i = 0; input.hasNextInt(); i++) < alist.add(input.nextInt()); System.out.println(i + " " + alist.get(i)); >System.out.println('x'); 

Edit: Just had to mention one of my favorite delimiters for Scanner, since it is so suitable here:

Scanner input = new Scanner(System.in).useDelimiter("\\D"); 

This will make a Scanner over just numbers, splitting on anything that is not a number. Combined with hasNextInt it also ends input on the first blank line when reading from terminal input.

Источник

How to handle infinite loop caused by invalid input (InputMismatchException) using Scanner

When a scanner throws an InputMismatchException, the scanner will not pass the token that caused the exception, so that it may be retrieved or skipped via some other method.

That means that if the next token is not an int , it throws the InputMismatchException , but the token stays there. So on the next iteration of the loop, reader.nextInt() reads the same token again and throws the exception again. What you need is to use it up. Add a reader.next() inside your catch to consume the token, which is invalid and needs to be discarded.

. > catch (InputMismatchException e) < System.out.println("Invalid value!"); reader.next(); // this consumes the invalid token >

+1 Note to readers: depending on the circumstance, you may want to use nextLine() instead of next() so that input like this has spaces in it doesn’t trigger multiple exceptions.

What I would do is read in the whole line using Scanner.nextLine(). Then create another scanner that reads the returned string.

String line = reader.nextLine(); Scanner sc = new Scanner(line); 

This would make your sample function something like this:

 public int readInt(String msg) < int num = 0; boolean loop = true; while (loop) < try < System.out.println(msg); String line = reader.nextLine(); Scanner sc = new Scanner(line); num = sc.nextInt(); loop = false; >catch (InputMismatchException e) < System.out.println("Invalid value!"); >> return num; > 

This way you have one scanner that gets the input and one that validates it so you don’t have to worry about reader caring if they input the correct form of input.

The guard of your while-do is ‘loop’ variable.

The exception itself thrown before your code reaches assignment loop = false; To be precise, the exception is thrown in previous statement which is num = reader.nextInt();

When exception thrown, value of ‘loop’ variable is ‘true’ but your code jumps to catch block and then repeats the while-do. This while-do will never stop because next iteration will throw an exception again, jumps to catch block again and so on.

To terminate this while-do, you need to guard your while-do with another logical thing such as :

This can be done in catch block or some other lines. But precise solution depends on your specifications.

Источник

Оцените статью