2

I'm apparently facing an infinite loop on while(input.hasNext()) , as in following code

File file = new File("data.txt");
Scanner input = new Scanner(file);

int sum = 0;

while (input.hasNext()) {
    if (input.hasNextInt()) {
        sum += input.nextInt();
    }
}
System.out.println(sum);

Some related questions explain why it always returns true if input stream is System.in, however I'm scanning through a File.

Please let me know where I'm going wrong.

I'm attempting to calculate the sum of unique integer values (space delimited where they occur).

Edit:

Lesson learned, input.hasNext() does not move the pointer to the next line and thus the scanner does not advance past any input. As explained in answers to this question as well as here .

Community
  • 1
  • 1
Abdullah Leghari
  • 2,332
  • 3
  • 24
  • 40
  • 6
    I think your `Scanner` have a next item which is not an `int`. You can test it using `input.next()` in an `else` statement :) – NiziL May 15 '14 at 11:25
  • 2
    http://stackoverflow.com/questions/8352040/scanner-on-text-file-hasnext-is-infinite – renz May 15 '14 at 11:27
  • 1
    Try adding input.next() in "else". – Leo Pflug May 15 '14 at 11:27
  • 1
    Glad to be helpful :) – NiziL May 15 '14 at 11:38
  • 1
    You say you're wanting "the sum of _unique_ integer values" - Is this really what you need, because if it is I don't think your current solution will meet this requirement. – Edd May 15 '14 at 11:43
  • Edd it is working fine in my case, all my ints are space delimited. It doesn't count values with no space before or after them, fortunately my input is consistent. – Abdullah Leghari May 15 '14 at 11:48
  • So if you gave it a file containing `2`, `3`, `2` are you expecting the `sum` to be `5` or `7`? I'm assuming the former, and don't see how your code will detect the duplicate `2`. – Edd May 15 '14 at 12:25
  • @Edd 2, 3, 2 will be 2 because 2, & 3, are not treated as Int. My values are something like, Edd 22 Leghari 11 (with more text as well in between) and I expect 33 (grand total) which it does. Text file is created using a PowerShell script so it is reasonably predictable :) – Abdullah Leghari May 15 '14 at 13:52
  • Sorry, I wasn't intending the comment to be counted. I don't want to keep adding comments if I've misunderstood, but the point I was trying to make was that the description sounds like you want "Nizil 22 Edd 22 Leghari 11" to total 33, which is not what you're doing. – Edd May 15 '14 at 13:55
  • You are right actually. Word 'unique' probably made it sound that way. I want sum of 'all' integer occurances. Thank you Edd – Abdullah Leghari May 15 '14 at 14:08

3 Answers3

5

Well, according to

while(input.hasNext()) {
  if(input.hasNextInt()) {
    sum += input.nextInt();
  }
}

Your scanner will not consume the next token if this token isn't an int, you can hilight this behavior with something like

int k=0;
while(input.hasNext()) {
  if(input.hasNextInt()) {
    sum += input.nextInt();
  } else {
    System.err.println("What ? It's not an integer...");
    if ( k < 1 ) {
      System.err.println("I'm gonna try again !");
      k++;
    } else {
      System.err.println("'"+input.next()+"' it's definitively not an integer");
      k=0;
    }
  }
}

Finally, there are many solutions, for example :

  • Modify your input file the remove all the non-integer token
  • Consume the non-integer token with Scanner::next()
  • Sanjeev's answer
NiziL
  • 5,068
  • 23
  • 33
4

You do not need to double checking on content. this should work:

   File file = new File("data.txt");
    Scanner input = new Scanner(file);

    int sum = 0;

    while(input.hasNextInt()) {
            sum += input.nextInt();
    }
    System.out.println(sum);

Hope this helps.

Sanjeev
  • 9,876
  • 2
  • 22
  • 33
  • It helped fix infinite loop however works with files having only integers, returns output 0 where I've some text. And else with input.next() solved it. Thanks for reply Sanjeev. – Abdullah Leghari May 15 '14 at 11:39
  • 1
    I do not know why this was downvoted, it's also correct depends only on OP if this is what he wants... – Betlista May 15 '14 at 11:40
  • @AbdullahLeghari but if the file have to contain only integers... we do not know ;-) – Betlista May 15 '14 at 11:41
0

Seems like scanner is reading a non int value from your file and when it does , while(input.hasNext()) will always be true because there is something as an input to scanner but it is not int. So scanner skips reading this non-int value in the inner if(input.hasNextInt()) check.

So scanner does not proceed beyond this element and always return true.

If you want to sum up all the integers in your file then you should modify your code to below:

while(input.hasNext()) {            
            if(input.hasNextInt()) {                
                sum += input.nextInt();
            }
            else
                input.next();
        }

Just read the non integer elements when scanner encouters it. Hope this clarifies.

  • That's really strange - "You last voted on this answer 2 hours ago. Your vote is now locked in unless this answer is edited.", but it was edited... I do not understand... – Betlista May 15 '14 at 14:41