i wrote this line (String str = sc.next();) like 10 times in my code, and all of them work ok except for one that doesn't wait for my input and immediately throws an exception "java.util.NoSuchElementException" !
does any one have an idea why that could happen ??
private static Matrix GetRationalMatrix(int[] size) throws Exception {
Scanner sc = new Scanner(System.in);
MathVector[] matrix = new MathVector[size[0]];
for(int i = 0 ; i < size[0] ; i++) {
MathVector vector = null;
String str = sc.nextLine();
str = str.replaceAll("[ \t]+", " ");
String[] splitStr = str.split(" ");
Scalar[] scalarVector = new Scalar[size[1]];
for(int j = 0 ; j < splitStr.length ; j++) {
String[] tmp = splitStr[j].split("/");
try {
scalarVector[j] = new Rational(Integer.parseInt(tmp[0]), Integer.parseInt(tmp[1]));
}
catch(Exception e){
sc.close();
throw new Exception("Please enter values properly: a/b were a,b are integers!");
}
}
vector = new MathVector(size[1], scalarVector);
matrix[i] = new MathVector(vector);
}
Matrix ans = new Matrix(size[0], matrix);
sc.close();
return ans;
}
in size[0] the number of rows and in size[1] number of columns , both will be positive integers
nextLine() instead of next();
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.
If you previously used
Scanner sc = new Scanner(System.in);
inside a try-with-resources or closed the Scanner yourself, that would have closed the underlying System.in stream. In that case, trying to read from it again through a Scanner would cause a NoSuchElementException.
Don't close System.in and try to re-use the same Scanner object.
java.util.NoSuchElementException is a RuntimeException which can be thrown by different classes in Java like Iterator, Enumerator, Scanner or StringTokenizer. All of those classes has method to fetch next element or next tokens if underlying data-structure doesn't have any element Java throws "java.util.NoSuchElementException".
u can use a string tokenizer in our code..
StringTokenizer st=new StringTokenizer(sc);
u can use hasMoretokens() method....so that it returns true as long as the input u provided have more tokens..... incase u want to get next token u can nextToken() method...
The javadoc for hasNext() specifies:
Returns true if this scanner has another token in its input. This method may block while waiting for input to scan. The scanner does not advance past any input.
The javadoc for next() specifies:
Finds and returns the next complete token from this scanner. A complete token is preceded and followed by input that matches the delimiter pattern. This method may block while waiting for input to scan, even if a previous invocation of hasNext() returned true.
That does not mean next() will always block, but it might block, say if it's waiting for the end of the token, since it promises to return the next complete token from the input. Checking whether the input contains another token is an entirely different operation, performed by hasNext(), which will block because it will wait for input (until EOF is found).
So I think you're getting NoSuchElementException because you are using next() improperly.
Related
I'm trying to get 2 integers from the user. This is the related part of my code:
public void play() {
int row=0,col=0;
initializeboard();
printboard();
do {
currentPlayer = players.remove(); //Returns currentPlayer
System.out.println("Ok, "+ currentPlayer.getname() + ", Enter your Move: Row[1-3] & Column[1-3]");
Scanner choice = new Scanner(System.in);
if (choice.hasNext()) {
row = choice.nextInt();
col = choice.nextInt();
while (row<1 || row>3 || col<1 || col>3 || board[row-1][col-1] != '-' ) {
System.out.println("Well, Move is not Valid or has already Been Selected, Try Again :/");
row = choice.nextInt();
col = choice.nextInt();
}
choice.close();
}
board[row][col] = currentPlayer.getsign(); //Places Sign in Game Board
printboard();
System.out.println();
players.append(currentPlayer); //Inserts the Next Player
} while(!win() && !isFull());
}
At first, it throws a NoSuchElementException, so I used .hasNext(). Now, it just skips the scanner and immediately invokes printboard().
The problem is that you are creating and then closing multiple Scanner objects with the same stream.
The answer from Peter Lawrey in this post explains why you shouldn't create multiple Scanner objects from the same stream. Here is a quote from the answer:
Once you close a stream it closes the underlying stream and you can't use it again. Only close System.in if you want to prevent it being used again.
The best thing is to create one final Scanner object (per stream) in your program and just pass it into methods when you want to use it:
static final Scanner scan = new Scanner(System.in);
Here is the problem :
do {
Scanner choice = new Scanner(System.in);
[...]
choice.close();
} while (!win() && !isFull());
You are opening a Scanner in a loop (first mistake) but more important, you are closing the Scanner.
Closing a Scanner also close the InputStream used, in your case System.in. You can't open that stream again so you will never be able to execute your loop twice.
public void close()
If this scanner has not yet been closed then if its underlying readable also implements the Closeable interface then the readable's close method will be invoked.
And this is in fact the problem you are facing. Once you have closed the first Scanner created and then try to open a new one, since System.in is closed, there is no value to read (hasNext return false). And you most likely enter an infinite loop since !win() && !isFull() will always give the same result.
I suggest not close it (in this case, this is not always a bad thing since it is a local variable, there is no risk).
Or simply use a parameter in the method to provide it (and still not closing it in the method). Let the main method manage the Scanner.
public void play(Scanner choice){
...
}
It might have been throwing the NoSuchElementException because you didn't input a integer.
The reason it "skips" over the Scanner is possibly because all hasNext evalutes is whether the System.in has a String contained in it. So it evalutes that expression and returns true or false. Your program then evaluates the expression in the while loop, possibly finding it to be false. Then finally moving on and invoking printboard.
I would suggest going back and changing hasNext to
row = choice.nextInt();
col = choice.nextInt();
Then make sure you are inputting integers.
I ran into an issue. Below is my code, which asks user for input and prints out what the user inputs one word at a time.
The problem is that the program never ends, and from my limited understanding, it seem to get stuck inside the while loop. Could anyone help me a little?
import java.util.Scanner;
public class Test{
public static void main(String args[]){
System.out.print("Enter your sentence: ");
Scanner sc = new Scanner (System.in);
while (sc.hasNext() == true ) {
String s1 = sc.next();
System.out.println(s1);
}
System.out.println("The loop has been ended"); // This somehow never get printed.
}
}
You keep on getting new a new string and continue the loop if it's not empty. Simply insert a control in the loop for an exit string.
while(!s1.equals("exit") && sc.hasNext()) {
// operate
}
If you want to declare the string inside the loop and not to do the operations in the loop body if the string is "exit":
while(sc.hasNext()) {
String s1 = sc.next();
if(s1.equals("exit")) {
break;
}
//operate
}
The Scanner will continue to read until it finds an "end of file" condition.
As you're reading from stdin, that'll either be when you send an EOF character (usually ^d on Unix), or at the end of the file if you use < style redirection.
When you use scanner, as mentioned by Alnitak, you only get 'false' for hasNext() when you have a EOF character, basically... You cannot easily send and EOF character using the keyboard, therefore in situations like this, it's common to have a special character or word which you can send to stop execution, for example:
String s1 = sc.next();
if (s1.equals("exit")) {
break;
}
Break will get you out of the loop.
Your condition is right (though you should drop the == true). What is happening is that the scanner will keep going until it reaches the end of the input. Try Ctrl+D, or pipe the input from a file (java myclass < input.txt).
it doesn't work because you have not programmed a fail-safe into the code. java sees that the scanner can still collect input while there is input to be collected and if possible, while that is true, it keeps doing so. having a scanner test to see if a certain word, like EXIT for example, is fine, but you could also have it loop a certain number of times, like ten or so. but the most efficient approach is to ask the user of your program how many strings they wish to enter, and while the number of strings they enter is less than the number they put in, the program shall execute. an added option could be if they type EXIT, when they see they need less spaces than they put in and don't want to fill the next cells up with nothing but whitespace. and you could have the program ask if they want to enter more input, in case they realize they need to enter more data into the computer.
the program would be quite simplistic to make, as well because there are a plethera of ways you could do it. feel free to ask me for these ways, i'm running out of room though. XD
If you don't want to use an EOF character for this, you can use StringTokenizer :
import java.util.*;
public class Test{
public static void main(){
Scanner sc = new Scanner (System.in);
System.out.print("Enter your sentence: ");
String s=sc.nextLine();
StringTokenizer st=new StringTokenizer(s," ");//" " is the delimiter here.
while (st.hasMoreTokens() ) {
String s1 = st.nextToken();
System.out.println(s1);
}
System.out.println("The loop has been ended");
}
}
I had the same problem and I solved it by reading the full line from the console with one scanner object, and then parsing the resulting string using a second scanner object.
Scanner console = new Scanner(System.in);
System.out.println("Enter input here:");
String inputLine = console.nextLine();
Scanner input = new Scanner(inputLine);
List<String> arg = new ArrayList<>();
while (input.hasNext()) {
arg.add(input.next().toLowerCase());
}
You can simply use one of the system dependent end-of-file indicators ( d for Unix/Linux/Ubuntu, z for windows) to make the while statement false. This should get you out of the loop nicely. :)
Modify the while loop as below. Declare s1 as String s1; one time outside the loop. To end the loop, simply use ctrl+z.
while (sc.hasNext())
{
s1 = sc.next();
System.out.println(s1);
System.out.print("Enter your sentence: ");
}
I got an run time exception in my program while I am reading a file through a Scanner.
java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Unknown Source)
at Day1.ReadFile.read(ReadFile.java:49)
at Day1.ParseTree.main(ParseTree.java:17)
My code is:
while((str=sc.nextLine())!=null){
i=0;
if(str.equals("Locations"))
{
size=4;
t=3;
str=sc.nextLine();
str=sc.nextLine();
}
if(str.equals("Professions"))
{
size=3;
t=2;
str=sc.nextLine();
str=sc.nextLine();
}
if(str.equals("Individuals"))
{
size=4;
t=4;
str=sc.nextLine();
str=sc.nextLine();
}
int j=0;
String loc[]=new String[size];
while(j<size){
beg=0;
end=str.indexOf(',');
if(end!=-1){
tmp=str.substring(beg, end);
beg=end+2;
}
if(end==-1)
{
tmp=str.substring(beg);
}
if(beg<str.length())
str=str.substring(beg);
loc[i]=tmp;
i++;
if(i==size ){
if(t==3)
{
location.add(loc);
}
if(t==2)
{
profession.add(loc);
}
if(t==4)
{
individual.add(loc);
}
i=0;
}
j++;
System.out.print("\n");
}
with Scanner you need to check if there is a next line with hasNextLine()
so the loop becomes
while(sc.hasNextLine()){
str=sc.nextLine();
//...
}
it's readers that return null on EOF
ofcourse in this piece of code this is dependent on whether the input is properly formatted
I also encounter with that problem.
In my case the problem was that i closed the scanner inside one of the funcs..
public class Main
{
public static void main(String[] args)
{
Scanner menu = new Scanner(System.in);
boolean exit = new Boolean(false);
while(!exit){
String choose = menu.nextLine();
Part1 t=new Part1()
t.start();
System.out.println("Noooooo Come back!!!"+choose);
}
menu.close();
}
}
public class Part1 extends Thread
{
public void run()
{
Scanner s = new Scanner(System.in);
String st = s.nextLine();
System.out.print("bllaaaaaaa\n"+st);
s.close();
}
}
The code above made the same exaption, the solution was to close the scanner only once at the main.
You're calling nextLine() and it's throwing an exception when there's no line, exactly as the javadoc describes. It will never return null
https://docs.oracle.com/javase/8/docs/api/java/util/Scanner.html
For whatever reason, the Scanner class also issues this same exception if it encounters special characters it cannot read. Beyond using the hasNextLine() method before each call to nextLine(), make sure the correct encoding is passed to the Scanner constructor, e.g.:
Scanner scanner = new Scanner(new FileInputStream(filePath), "UTF-8");
Your real problem is that you are calling "sc.nextLine()" MORE TIMES than the number of lines.
For example, if you have only TEN input lines, then you can ONLY call "sc.nextLine()" TEN times.
Every time you call "sc.nextLine()", one input line will be consumed. If you call "sc.nextLine()" MORE TIMES than the number of lines, you will have an exception called
"java.util.NoSuchElementException: No line found".
If you have to call "sc.nextLine()" n times, then you have to have at least n lines.
Try to change your code to match the number of times you call "sc.nextLine()" with the number of lines, and I guarantee that your problem will be solved.
Need to use top comment but also pay attention to nextLine(). To eliminate this error only call
sc.nextLine()
Once from inside your while loop
while (sc.hasNextLine()) {sc.nextLine()...}
You are using while to look ahead only 1 line. Then using sc.nextLine() to read 2 lines ahead of the single line you asked the while loop to look ahead.
Also change the multiple IF statements to IF, ELSE to avoid reading more than one line also.
I ran into this problem, my structure was:
1 - System
2 - Registration <-> 3 - validate
I was closing Scanner on each of the 3 steps. I started to close the Scanner only in system and it solved.
I'm trying to print a string in reverse. i.e.
hello world
should come out as:
dlrow olleh
But the outcome only shows the reverse of the first word. i.e.
olleh
Any thoughts?
import java.util.Scanner;
public class test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
System.out.println("Input a string:");
String s;
s = input.next();
String original, reverse = "";
original = s;
int length = original.length();
for ( int i = length - 1 ; i >= 0 ; i-- )
reverse = reverse + original.charAt(i);
System.out.println("Reverse of entered string is: "+reverse);
input.close();
}
}
Using input.next() only stores the next word in the variable (only "hello"). Try this:
System.out.println("Input a string:");
String s;
s = input.nextLine();
System.out.println("entered: " + s);
The line
s=input.next()
will only take one word.
So to get the whole line 'hello world', you've to use the nextLine() function.
s = input.nextLine();
Your scanner object returns only the next complete token through the input.next() method. A token is considered complete when there is a whitespace character. Use the nextLine() method of the scanner to get the complete input if you are using multiple words.
new StringBuilder("hello world").reverse().toString();
Maybe much more simpler.
use s.nextline() instead of s.next() as s.next() read only first token string
Scanner sc= new Scanner(System.in);
String s = sc.nextLine();
System.out.println(new StringBuilder(s).reverse().toString());
From Scanner javadoc:
public String next()
Finds and returns the next complete token from this scanner. A
complete token is preceded and followed by input that matches the
delimiter pattern. This method may block while waiting for input to
scan, even if a previous invocation of hasNext() returned true.
What happens is that the token delimiter may not be what you're expecting (newline, for instance).
If you wish your program to read the entire line input by the user, you might want to use Scanner.nextLine(), which will read the entire line input by the user, or maybe Scanner.next(String delimiter), which will allow you to enter the desired token delimiter.
Change s = input.next() to s = input.nextLine()
I can't really write some source code but maybe try using two different inputs. After that add each string to it's own variable. After that, reverse them both and add them together as an output.
This question already exists:
Scanner issue when using nextLine after nextXXX [duplicate]
Closed 9 years ago.
I have problem with Scanner
When I run the program it skips this one after
System.out.println("name");
n1=s.nextLine();
This is the program "CEmploye " is a class
package Ex5_2;
import java.util.*;
public class XXXX {
public static void main(String[] args) {
int input;
int c1 ;
String n1;
Date d1 = null;
float p1;
float [] t = new float[3];
System.out.println("give nb of emp");
Scanner s = new Scanner(System.in);
input=s.nextInt();
Vector v = new Vector(input);
for(int i=0 ;i <input;i++)
{
System.out.println("cin");
c1=s.nextInt();
System.out.println("name");
n1=s.nextLine();
System.out.println("price");
p1=s.nextFloat();
for(int k=0 ; k<3;k++)
{
System.out.println("nb of hour");
CEmploye.tab[k]=s.nextFloat();
}
CEmploye emp = new CEmploye(c1,n1,d1,p1);
emp.CalculSalaire();
System.out.println(emp.salaire);
}
}
}
Can anyone give me solution ?
System.in's buffer isn't flushed until it gets a newline. So you can't use nextInt() or nextFloat() because they block until a newline.
You'll need to read everything on a line by itself then parse it (with some validation as needed):
cl = Integer.parseInt(s.nextLine());
and
pl = Float.parseFloat(s.nextLine());
and
CEmploye.tab[k]=Float.parseFloat(s.nextLine());
You can't use n1=s.nextLine(); with n1=s.nextInt(). Use n1=s.next();
nextInt() only reads the next integer available and leaves a newline character in the inputstream.
Your s.nextLine() then gets consumed thus not prompting for additional inputs.
Simply add another nextLine() to read more lines
c1=s.nextInt();
This just reads the integer value not the end of line. So when you do
n1=s.nextLine();
it just reads the end of line that you provided by pressing the enter while providing the integer input for the previous variable (c1) and thus seems like it skipped the input. (If you put an integer and some string in the same line when taking c1 input, you will get values for c1 and n1 both. You can check the same)
In order to fix it, either put nextLine() input after each nextInt(). Hope it helps.