Scanner Class hasNextLine infinite loop - java

why does this piece of code go into an infinite loop when I try to give it a basic text file?
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
public class TestFile
{
public static void main(String args[]) throws IOException
{
// Read in input file
File input = new File(args[0]);
Scanner freader = new Scanner(input);
while (freader.hasNextLine()) {
System.out.println("hi");
}
freader.close();
}
}
The print line just keeps going.

Because hasNexLine() does neither get the line nor change the state of the scanner. if it's true once, and no other methods of the scanner are called, it'll always be true.

Because you have to consume the nextLine so the code should be:
while ( theScanner.hasNextLine() ) {
String theLine = theScanner.nextLine();
}
If you don't invoke nextLine() you will always be watching at the same line and it will always answer true to that.

Add a call to nextLine or any other Scanner method that'll read in some input inside the while loop.
At the moment you're just repeatedly calling hasNextLine (which only returns a boolean, it doesn't modify the stream) without retrieving any input from freader, so if freader initially has another line within its input hasNextLine will always return true and your loop is essentially while (true).

Related

hasNextLine() always returning true within While Loop

This question is linked to a previous question I asked regarding the same program, which can be viewed here:
Writing to a file code causing an endless loop
I have fixed the problem above and rewritten the function as a while loop rather than do while, but now I have the opposite problem that nothing is being written to the file. I've inserting a print statement to tell me the status of hasNextLine, and it is always returning as true even when a blank line has been entered, which is when I want the writer to terminate.
Here is the updated code:
import java.util.Scanner;
import java.io.FileNotFoundException;
import java.io.PrintWriter;;
public class Lab_Week8_WriteAStory {
public static void main(String[] args) throws FileNotFoundException {
Scanner whatToWrite = new Scanner (System.in);
PrintWriter writing = new PrintWriter ("Read and Write Files/output.txt");
while (whatToWrite.hasNextLine()){
String writeToFile = whatToWrite.nextLine();
writing.println(writeToFile);
System.out.println (whatToWrite.hasNextLine());
}
writing.close();
whatToWrite.close();
}
}
Check the documentation for Scanner.hasNextLine():
Returns true if there is another line in the input of this scanner. This method may block while waiting for input. The scanner does not advance past any input.
This is what's happening. Since you are using System.in as input source, the method is waiting for your input and once you provide it, it returns true and proceed to the next line and the process repeats itself.

Java Using Scanner to Read File and Then Read Line

I'm trying to make a scanner that reads a file and deletes the spaces between each word. I can get this much but I can't get it to where they stay on the same line. I can't get the program to read a line, delete the spaces, and then go to the next line. This is the text from my practice project:
four score and
seven years ago our
fathers brought forth
on this continent
a new
nation
I'm currently only getting the first line
and this is my code:
import java.util.*;
import java.io.*;
public class CollapseSpace {
public static void main (String[] args) throws FileNotFoundException{
Scanner fileInput = new Scanner(new File ("textwithspaces.txt"));
String nextLine = fileInput.nextLine();
Scanner lineInput = new Scanner(nextLine);
while(fileInput.hasNext()){
nextLine = fileInput.nextLine();
while(lineInput.hasNext()){
System.out.print(lineInput.next() + " "); // I tried to add a fileInput.NextLine() to consume the line but it isn't working properly
}
System.out.println();
}
}
}
If you only need to iterate line by line and remove spaces between words then you only need one loop, sample code below should do the trick
public static void main (String[] args) throws FileNotFoundException{
final Scanner fileInput = new Scanner(new File ("src/main/resources/textwithspaces.txt"));
while(fileInput.hasNext()){
final String nextLine = fileInput.nextLine();
// remove all spaces
final String lineWithOutSpaces = nextLine.replaceAll("\\s+","");
System.out.println(lineWithOutSpaces);
}
}
First of all, you shouldn't be using * to import classes. It is generally thought of as "bad practice" since it can interfere with your own classes, also it is not very explicit.
You need to loop the nextLine method inside your own loop. And also using a replaceAll method of the string would be good.
I have shown an example below:
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
class Main {
public static void main(String[] args) throws FileNotFoundException {
// Create an object to represent a text file
File file = new File("textwithspaces.txt");
// Create a scanner with the text file as argument
Scanner scannerWithFile = new Scanner(file);
// Continue as long as it has a next line
do {
// Replace strings
String thisLine = scannerWithFile.nextLine();
// Only print the line out if not empty
if (!thisLine.isEmpty()) {
// Replace all spaces
thisLine = thisLine.replaceAll(" ", "");
// Print
System.out.println(thisLine);
}
} while (scannerWithFile.hasNext());
}
}
I also switched your while loop to a do while loop, this is so you can just instantly go into the loop without having to check for a condition first, it is done before next iteration.
Your biggest problem is that you declared nextLine = fileInput.nextLine(); outside of the loop, and then used that in Scanner lineInput = new Scanner(nextLine); so it becomes the first line of the text, but then never changes.
I also agree with the other comment that says you shouldn't be using *, it's considered bad practice to import broadly like that, as you're importing a whole lot of stuff you won't be using.
I reconstructed your code to make it work.
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
public class Main {
public static void main (String[] args) throws FileNotFoundException{
Scanner fileInput = new Scanner(new File ("textwithspaces.txt"));
while(fileInput.hasNext()){
String nextLine = fileInput.nextLine();
Scanner lineInput = new Scanner(nextLine);
while(lineInput.hasNext()){
System.out.print(lineInput.next() + " ");
}
System.out.println();
}
}
}

Reading file of unspaced integers – hasNextInt() never returns true

I'm trying to read a list of unspaced integers from a file and I can't figure out why I never get past the conditional in my while loop.
This is the entire "nums.txt" file:
12121212121212121212121212121212
00001212121212121212121212121212
33331212121212121212121212121212
And the little script looks like this:
import java.util.Scanner;
import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileNotFoundException;
public class Test{
public static void main(String[] args){
try{
Scanner reader = new Scanner(new BufferedReader(new FileReader(new File("nums.txt"))));
while(reader.hasNextInt()){
System.out.println(reader.nextInt());
}
reader.close()
}
catch(FileNotFoundException e){
e.printStackTrace();
}
}
}
When run, this outputs nothing, and terminates.
According to its JavaDoc Scanner.hasNextInt():
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.
12121212121212121212121212121212 is the next token, and it can't be interpreted as an int, because the maximum int is 2147483647.
Therefore hasNextInt() returns false, and your loop ends.
A Scanner by its nature works on tokens split by a delimiter (by default, space). If you want to consume one char at a time use Reader.read() or even InputStream.read().
Something like this should work for you. Be sure to do something with each int that gets generated or you'll loose it.
BufferedReaderreader = new new BufferedReader(new FileReader(new File("nums.txt")));
while ((currentChar = br.read()) != null) {
// discard white space
if (!java.lang.Character.isWhitespace(currentChar))
int x = Integer.parseInt(currentChar)
// do something with the int
}
A functional solution to this issue, by reading chars and returning the values as they are in the file:
BufferedReader reader = new BufferedReader(new FileReader(new File("nums.txt")));
while(reader.read()%48 != -1){
System.out.println(reader.read()%48);
}
Because the file could contain newlines and other characters, one would need to do additional parsing to accept only the desired numbers as they are returned.
Or using Scanner:
Scanner reader = new Scanner(new File("nums.txt"));
while(reader.hasNextLine())
for (String token : reader.nextLine().split("(?!^)"))
System.out.println(token);

Scanner class , hasNextLine give true even there is not any next line

My input txt file has this content:
aa1 aa2
bb1 bb2
cc1 cc2
After cursor is going to the last line, how does hasNextLine() method give true while reading cc1 and cc2? I thought I would only get aa1 to bb2.
Output:
aa1
aa2
bb1
bb2
cc1
cc2
package test;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Test {
public static void main(String[] args) throws FileNotFoundException {
File f = new File("K:\\Test\\a.txt");
System.out.println(f.exists());
Scanner reader = new Scanner(f);
while (reader.hasNextLine()) {
System.out.println(reader.next());
}
}
}
Either use hasNextLine() with nextLine(), or use hasNext(), with next(). Mixing those can result in undesired behavior (unless used deliberately). See their documentation here. Quoting the next() method:
Returns the next token if it matches the specified pattern. This method may block while waiting for input to scan, even if a previous invocation of hasNext(Pattern) returned true. If the match is successful, the scanner advances past the input that matched the pattern.
And also, in the Scanner class documentation, you can find this:
A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace.
So, the scanner reads the first line, it advances to the first delimiter (the white space) and prints the first part (aa1). Then, still on the same line, it prints the second part (aa2). Then, it moves to the second line, prints (bb1), then it prints (bb2), and still the while condition is true, since there is also a next line. So, finally, at the third line, it prints the first part (cc1), it prints the second part (cc2) and then stops, since there is no other line.

Java code hangs at Scanner hasNextLine

First off, I'm new to java and trying to complete an assignment from school on creating a vending machine. My program is taking in 2 files as cli arguments, one for products, and the other for money.
For the life of me I cannot figure out why the code is hanging on line 42
(while (moneyTemp.hasNextLine());)
I tried to debug on eclipse using breakpoints and noticed the code never goes past this line. Putting a print statement inside the while loop, i don't get the output so i know it is not looping.
The java docs say hasNextLine can block waiting for user input, but since my source is a file, I'm not sure why this is happening. See relevant code below.
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
public class VendingMachine
{
static Scanner input = new Scanner (System.in);
public static void main(String[] args)
{
try
{
Scanner productTempFile = new Scanner(new File(args[0]));
Scanner moneyTemp = new Scanner(new File(args[1]));
int numProducts = 0; //Number of products to be loaded to the machines
int numMoney = 0; //Number of money objects to be loaded in the machine
while (productTempFile.hasNextLine()) //This block will get the number of products
{
numProducts++;
productTempFile.nextLine();
}
productTempFile.close();
Product[] invArray = new Product[numProducts];
Scanner myFile = new Scanner(new File(args[0]));
for(int i = 0; i < numProducts; i++) //This block populates the array of products
{
String inputLine = myFile.nextLine();
String[] lineArray = inputLine.split(",");
invArray[i] = new Product(lineArray[0], Double.valueOf(lineArray[1]), lineArray[2], lineArray[3],
Double.valueOf(lineArray[4]), Integer.valueOf(lineArray[5]));
}
myFile.close();
System.out.println("I'm here");
while (moneyTemp.hasNextLine()); //This block gets the number of different money items
{
numMoney++;
moneyTemp.nextLine();
}
Below is the second file i am supplying ie arg[1] which is formatted same like first one which works.
PaperCurrency,100 Dollar Bill,100.0,medium,paper,0
PaperCurrency,50 Dollar Bill,50.0,medium,paper,0
PaperCurrency,20 Dollar Bill,20.0,medium,paper,0
PaperCurrency,10 Dollar Bill,10.0,medium,paper,4
PaperCurrency,5 Dollar Bill,5.0,medium,paper,8
PaperCurrency,1 Dollar Bill,100.0,medium,paper,16
CoinCurrency,50 Cent Piece,0.5,large,metal,10
CoinCurrency,Quarter,0.25,medium,metal,20
CoinCurrency,Dime,0.1,small,metal,30
CoinCurrency,Nickel,0.05,small,metal,40
CoinCurrency,Penny,0.01,small,metal,50
Any help will be very appreciated.
Thanks
Remove semicolon from the line
while (moneyTemp.hasNextLine());
Semicolom make the while loop complete its body without doing anything means its like while(){} when while condition is true do nothing and since your condition is hasNextLine() it checks for same line again and again causing infinite loop.
By adding the semicolon (;), you are implicitly having the while loop execute an empty block. hasNextLine() doesn't doesn't change the InputStream the scanner is based on, so since there's nothing in the while loop's body, there's nothing to change the state, and the loop will just continue forever.
Just drop the semicolon from the while loop, and you should be fine:
while (moneyTemp.hasNextLine()) // no ; here!
{
numMoney++;
moneyTemp.nextLine();
}

Categories