Runtime Error Using Scanner class [duplicate] - java

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.

Related

Java display file line by line using Enter key

I'm trying to progress displaying a file line by line with an Enter key, but the if statement that I try doesn't seem to work. If I disregard the if statement, it works, but it feels incomplete because then I'm asking for input and doing nothing with it.
This is what I have:
import java.util.Scanner;
import java.io.*;
public class LineByLine {
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(System.in);
System.out.println("What is the filename?");
String input = in.nextLine();
BufferedReader buff = new BufferedReader(new FileReader(input));
String sen = buff.readLine();
System.out.println(sen);
Scanner enter = new Scanner(System.in);
while (sen != null){
String output = enter.next();
if (output.equals("")){
System.out.println(sen = buff.readLine());
}
}
}
}
I just don't know why my if statement doesn't work.
The core issue is that you misunderstand Scanner and its default configuration: Out of the box, scanner splits on any amount of whitespace. .next() asks for the next token; a token is the thing that appears in between the whitespace.
Thus, pressing enter 500 times produces zero tokens. After all, tokens are what's in between the separator, and the default separator is 'any amount of whitespace'. Pressing enter a bunch of time is still just you entering the same separator.
The underlying problem is that most people appear to assume that Scanner reads one line at a time. It doesn't do that. At all. But you want it to. So, tell it to! Easy peasy - make scanner do what you already thought it did:
Scanner in = new Scanner(System.in);
in.useDelimiter("\\R"); // a single enter press is now the separator.
You should also stop using nextLine on scanners. nextLine and any other next call do not mix. The easiest way to solve this problem is to only ever use nextLine and nothing else, or, never use nextLine. With the above setup, .next() gets you a token which is an entire line - thus, no need for nextLine, which is good news, as nextLine is broken (it does what the spec says it should, but what it does is counterintuitive. We can debate semantics on whether 'broken' is a fair description of it. Point is, it doesn't do what you think it does).
Also, while you're at it, don't make multiple scanners. And, to improve this code, resources must be properly closed. You're not doing that. Let's use try-with, that's what it is for.
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(System.in);
in.useDelimiter("\\R");
System.out.println("What is the filename?");
String input = in.next();
try (BufferedReader buff = new BufferedReader(new FileReader(input))) {
String sen = buff.readLine();
System.out.println(sen);
while (sen != null){
enter.next(); // why does it matter _what_ they entered?
// as long as they pressed it, we're good, right? Just ignore what it returns.
System.out.println(sen = buff.readLine());
}
}
}

Scanner.next() and hasNext() creating infinite loop when reading from console [duplicate]

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: ");
}

Why does this code using nextInt() loops forever? [duplicate]

This question already has answers here:
Endless while loop problem with try/catch
(2 answers)
Closed 7 years ago.
Below code,
import java.util.Scanner;
public class Dummy {
static Scanner sc = new Scanner(System.in);
public static int getIntegerInput(String prompt){
int choice = 0;
for(;;){
System.out.print(prompt);
try{
choice = sc.nextInt();
break;
}catch(java.util.InputMismatchException ex){
System.out.print("What??? ");
}
}
return choice;
}
public static void main(String[] args) {
int choice = getIntegerInput("Enter a number: ");
} //end main
}
does not stop for next user input, if the first user input raised an exception.
How do I understand this problem in the above code? placing sc.next() in catch resolves the problem. But I'm still not clear what is going on under the hood? What is the right approach to resolve this problem?
When nextXYZ() fails to consume a token it leaves it in the InputStream. Here, you are looping over the same input endlessly - each iteration, you attempt to consume this token, throw an exception if it isn't an integer, catch it, and try reading it again - forever.
EDIT:
In order to work around this, you could use next() to consume that token and move on to the next one:
for(;;) {
System.out.print(prompt);
try{
choice = sc.nextInt();
break;
} catch(java.util.InputMismatchException ex) {
sc.next(); // here
}
}
The problem with Scanner next() are they will not advances if the match is not found. And the character for which it failed remain in the stream. Hence its very important to advance the scanner if you found non intended character.
You can use next() method which actually consumes any character or you can use skip method passing skip pattern.
Use hasNext() to know whether a valid match is present or not. If not then consume that character using above said methods.
If it doesnt find an int on the next like, it throws an error. This error is then caught by your program, so the break is never hit because the error jumps over it whenever a non-int (including nothing) is found.

Incorrect example of Scanner in Java book?

I'm practicing HashSet from Java book by Cay S. Horstmann and Gary Cornell and I think there's a mistake in example code on page 687. We have a Scanner importing words to HashSet and it looks like this (I removed some unneeded code to make a problem more visible):
Set<String> words = new HashSet<String>();
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
String word = in.next();
words.add(word);
}
The problem is there's no way stop this loop. Or maybe there's something I'm missing?
To stop the loop I've added another static helper method:
public static boolean isStop(Scanner in) {
if (in.next().equals("stop")) {
return true;
}
return false;
}
And now the main code looks like this:
Set<String> words = new HashSet<String>();
Scanner in = new Scanner(System.in);
while (!isStop(in)) {
String word = in.next();
words.add(word);
}
Is there any other way to stop scanner loop? I can't believe that book's author has made a mistake ?
The loop stops as soon as this condition is false:
in.hasNext()
I.e., there are no more words.
Inside the loop is a command to read the next word:
in.next()
So words will continue to be read until the Scanner has no more words to read. This loop will terminate at the end of whatever the Scanner is reading.
Since you are scanning System.in, the loop won't stop as it will keep on adding "words" to your Set but there's no visible error in the program.
Your idea of selecting a keyword to stop the loop once a user input matches that keyword sounds good.
You don't really need a static method using your Scanner as argument for that.
Just add the following after String word = in.next();:
if (word.equalsIgnoreCase("stop")) {
System.out.printf("Quitting with set: %s%n", words);
in.close();
return; // assuming method is void
}
The scanner will continue while there are still words in the input, as others explained. Note that when we're talking about System.in, it usually waits until the user enters more text, and so will not terminate until the user closes the stream (supplies the appropriate end-of-file for the operating system). In Unix/Linux, for the loop to terminate, the user will need to use control-D.
The loop won't stop as it will keep on adding "words" to your Set but there's no visible error in the program.
Your idea of selecting a keyword to stop the loop once a user input matches that keyword sounds good.
You don't really need a static method using your Scanner as argument for that.
Just add change your code as follows:
Set<String> words = new HashSet<String>();
Scanner in = new Scanner(System.in);
System.out.print("Type a word...");
while (in.hasNext()) {
String word = in.next();
if (word.equalsIgnoreCase("stop")) {
System.out.printf("Quitting with set: %s%n", words);
return; // assuming method is void
}
else {
words.add(word);
System.out.print("Type a word (or \"stop\" to quit)...");
}
}
IF there is code to be executed after the loop then yes, I'd say the authors made a mistake. Write to them about it! If this is an example of adding items to a Set then the example is fine. It all depends on what the authors' intent of the example was.
hasNext() is a blocking method meaning it will always wait for more input. There are related questions about this. Your way of "fixing this" is what the general consensus has done.

How to get out of while loop in java with Scanner method "hasNext" as condition?

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: ");
}

Categories