Scanner on text file hasNext() is infinite
Asked Answered
U

4

6

I'm writing a simple program in Java and it requires reading data from a text file. However, I'm having trouble counting lines. The issue seems generic enough for a simple Google search but I may not even be searching the right things.

The textbook I'm learning from suggests that to count the number of lines in a text file, you should do something like this:

public static int[] sampleDataArray(String inputFile) throws IOException
{
        File file = new File(inputFile);
        Scanner inFile = new Scanner(file);

        int count = 0;

        while (inFile.hasNext())
            count++;

        int[] numbersArray = new int[count];

        inFile.reset();
        for (int i = 0; i < count; i++)
        {
            numbersArray[i] = inFile.nextInt();
        }

        inFile.close();
        return numbersArray;
}

It seems to me that the while (inFile.hasNext()) line is the problem. I think the hasNext() is running infinitely. The data file that I'm using with the code definitely has a finite number of lines of data.

What should I do?

Urbanity answered 2/12, 2011 at 5:13 Comment(1)
Replace int[] by List<Integer>. This way you don't need to know the size beforehand and it saves you from one more loop.Dusky
H
13

After you call hasNext() the first time if you don't read from the file hasNext() will always return true. Because the front of the input doesn't change.

Imagine you have a file with this line in it:

this is input

If you call hasNext() on this file, it will return true because there is a next token in the file, in this case the word this.

If you don't read from the file after this initial call, the "next" input to be processed is STILL the word this. The next input doesn't change until you read from the file.

TL;DR

When you call hasNext() read from the file, otherwise you will always have an infinite loop.

Additionally

If you really want to use hasNext(), or would like to, you could create another Scanner object and read through the file to count the lines, then your loop would work fine. also, you should really use hasNextLine()

public int countLines(File inFile)
{
   int count = 0;
   Scanner fileScanner = new Scanner(inFile);

   while(fileScanner.hasNextLine()) //if you are trying to count lines
   {                                //you should use hasNextLine()
       fileScanner.nextLine() //advance the inputstream
       count++;
   }

   return count;
}

Hope this is helpful.

Headrail answered 2/12, 2011 at 5:22 Comment(1)
Exactly what I wanted to know. Thanks!Urbanity
V
8

inFile.hasNext() does not move the pointer to the next line

try this

String x=null;
while((x = inFile.next()) != null)
     count++;

description of hasNext()

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.

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Scanner.html#hasNext%28%29

Vertu answered 2/12, 2011 at 5:15 Comment(4)
But doesn't think count the number of tokens in a file, not the number of lines?Headrail
Short, simple, and sweet. I just couldn't get it to work. Maybe I did something wrong?Urbanity
I am sorry, it didnt work for you, by the way what error did you get ? @UrbanityVertu
Haha please don't apologize. This is my first time using Stack Overflow and I am SUPER impressed with how helpful everyone is. I'll try using your code again; I'll update this with the error when I get to it. Thank you so much for all your help!Urbanity
I
2

For counting number of lines use hasNextLine(), instead of hasNext().
In while loop you are supposed to call nextLine(), because in your current implementation scanner is static on first line. Calling this method will make it to move to the next line, in every iteration of loop.

Refer to the following code snippet:

while (inFile.hasNextLine()){
  inFile.nextLine()
  count++;
}
Ileum answered 2/12, 2011 at 10:11 Comment(0)
C
1

You can not use the scanner to count the no of line in file because as default scanner uses white space to separate tokens. I would suggest to use BufferReader and readline method.

http://docs.oracle.com/javase/6/docs/api/java/io/BufferedReader.html

private Integer getNoOfLines( String fileName) throws FileNotFoundException,
        IOException {
    FileInputStream fstream = new FileInputStream(fileName);
    DataInputStream in = new DataInputStream(fstream);
    BufferedReader br = new BufferedReader(new InputStreamReader(in));
    String strLine;
    List<String> lineList = new ArrayList<String>();
    while ((strLine = br.readLine()) != null) {
        lineList.add(strLine);
    }
    in.close();
    return lineList.size();
}
Cesya answered 2/12, 2011 at 5:27 Comment(1)
You CAN use a Scanner to count the lines in a file. hasNext() uses whitespace to separate tokens by default, but hasNextLine() doesn't. Also, you can set whatever delimiter you want to separate tokens.Headrail

© 2022 - 2024 — McMap. All rights reserved.