13

So here is my code:

public static void getArmor(String treasure)
    throws FileNotFoundException{
    Random rand=new Random();
    Scanner file=new Scanner(new File ("armor.txt"));
    while(!file.next().equals(treasure)){
        file.next(); //stack trace error here
        }
    int min=file.nextInt();
    int max=file.nextInt();
    int defense=min + (int)(Math.random() * ((max - min) + 1));
    treasure=treasure.replace("_", " ");
    System.out.println(treasure);
    System.out.println("Defense: "+defense);
    System.out.println("=====");
    System.out.println();
    }

public static void getTreasureClass(Monster monGet)
throws FileNotFoundException{
    Random rand = new Random();
    String tc=monGet.getTreasureClass();
    while (tc.startsWith("tc:")){
        Scanner scan=new Scanner(new File ("TreasureClassEx.txt"));
        String eachLine=scan.nextLine();
        while(!tc.equals(scan.next())){
        eachLine=scan.nextLine();
        }
        for (int i=0;i<=rand.nextInt(3);i++){
            tc=scan.next();
        }
    getArmor(tc); //stack trace error here
    }
 }

For some reason I get a No Such Element Exception

    at java.util.Scanner.throwFor(Scanner.java:907)
at java.util.Scanner.next(Scanner.java:1416)
at LootGenerator.getArmor(LootGenerator.java:43)
at LootGenerator.getTreasureClass(LootGenerator.java:68)
at LootGenerator.getMonster(LootGenerator.java:127)
at LootGenerator.theGame(LootGenerator.java:19)
at LootGenerator.main(LootGenerator.java:11)

I'm not sure why though. Basically my program is searching through two text files - armor.txt and TreasureClassEx.txt. getTreasureClass receives a treasure class from a monster and searches through the txt until it reaches a base armor item (a string that does not start with tc:.) It then searches getArmor for an armor that matches the name of the base armor it got in treasure class. Any advice would be appreciated! Thanks!

The link to the txt files is here: http://www.cis.upenn.edu/~cis110/hw/hw06/large_data.zip

Akaraka
  • 173
  • 1
  • 2
  • 11

5 Answers5

16

It looks like you are calling next even if the scanner no longer has a next element to provide... throwing the exception.

while(!file.next().equals(treasure)){
        file.next();
        }

Should be something like

boolean foundTreasure = false;

while(file.hasNext()){
     if(file.next().equals(treasure)){
          foundTreasure = true;
          break; // found treasure, if you need to use it, assign to variable beforehand
     }
}
    // out here, either we never found treasure at all, or the last element we looked as was treasure... act accordingly
Bryan
  • 2,139
  • 18
  • 27
  • I tried out your code for that but then I get a no such element exception for my min/max nextInt(), which is weird because doesn't the loop break when it equals the treasure? Shouldn't there still be a next int after that? I linked the txt files in my main post by the way, the relevant one is armor.txt and TreasureClassEx.txt. Thanks! – Akaraka Nov 07 '11 at 02:30
  • 1
    I edited my response to be a little more clear. It may be possible that you are not finding treasure at all... so your calls to nextInt would fail here since there are no more tokens to read. I would test with something like the above code, and add a debug to see if file.next().equals(treasure) is ever evaluated as true. – Bryan Nov 07 '11 at 02:33
0

I had run into the same issue while I was dealing with large dataset. One thing I've noticed was the NoSuchElementException is thrown when the Scanner reaches the endOfFile, where it is not going to affect our data.

Here, I've placed my code in try block and catch block handles the exception. You can also leave it empty, if you don't want to perform any task.

For the above question, because you are using file.next() both in the condition and in the while loop you can handle the exception as

while(!file.next().equals(treasure)){
    try{
        file.next(); //stack trace error here
       }catch(NoSuchElementException e) {  }
}

This worked perfectly for me, if there are any corner cases for my approach, do let me know through comments.

Giri
  • 2,546
  • 2
  • 20
  • 27
  • 2
    [empty catch blocks are generally a bad idea](https://stackoverflow.com/questions/1234343/why-are-empty-catch-blocks-a-bad-idea) – Amani Kilumanga Mar 16 '16 at 06:59
0

Another situation which issues the same problem, map.entrySet().iterator().next()

If there is no element in the Map object, then the above code will return NoSuchElementException. Make sure to call hasNext() first.

Rakesh Balan
  • 61
  • 1
  • 2
-1

I Know this question was aked 3 years ago, but I just had the same problem, and what solved it was instead of putting:

 while (i.hasNext()) {
    // code goes here 
}

I did one iteration at the start, and then checked for condition using:

do {
   // code goes here
} while (i.hasNext());

I hope this will help some people at some stage.

Yakuman
  • 153
  • 9
  • Switching from while to do..while can not avoid the exception in general, it will on the contrary lead to the exception if the first call to next() fails. – Martin Meeser May 12 '20 at 19:47
-1

Looks like your file.next() line in the while loop is throwing the NoSuchElementException since the scanner reached the end of file. Read the next() java API here

Also you should not call next() in the loop and also in the while condition. In the while condition you should check if next token is available and inside the while loop check if its equal to treasure.

Aditya Naidu
  • 1,362
  • 9
  • 12