3
Scanner s = new Scanner(new File("src/mail_list"));    
while (s.hasNextLine()){
        String line1 = s.nextLine();
        if (line1.startsWith("Users")){
            line1 = s.nextLine();
            while (!(line1 = s.nextLine()).isEmpty()) {
                String arr[] = line1.split(" ", 4);
                users.add(new User(arr[0],arr[1],arr[2],arr[3]));
            }
        }
        if (line1.startsWith("Lists")){
            line1 = s.nextLine();
            while (!(line1 = s.nextLine()).isEmpty()) { //exception here
                String arr1[] = line1.split(" ", 2);
                ArrayList<String> tmp = new ArrayList<String>();
                StringTokenizer st = new StringTokenizer(arr1[1]);
                while (st.hasMoreTokens()) {
                    tmp.add(st.nextToken());
                }
                list.add(new List((arr1[0]), tmp));
            }
        }
    }

/*-testfile-start*/
Keyword: Users
username1 Name1 Surname1 email1
username2 Name2 Surname2 email2

Keyword: Lists
list_name username1 username2 ...
/*-testfile-end*/

I'm using the above code in order to sort things from the above testfile pattern. Basically it means that if I encounter the keyword "Users" I have to add the said info about the user.

I marked in the code where the exception rises. Any ideas on how to counter it?

Null
  • 1,950
  • 9
  • 30
  • 33
Pavlos Panteliadis
  • 1,495
  • 1
  • 15
  • 25

5 Answers5

1

You are calling nextLine() twice but only checking hasNextLine() once.

String line1 = s.nextLine();
    if (line1.startsWith("Users")){
        line1 = s.nextLine();

Meaning you are getting the next line without knowing if there is one, which throws the exception if there isn't one.

alenz316
  • 613
  • 3
  • 10
1

I found a stupid solution to it. I just added a 'dummy' char 2 lines after the last line. and it works. It's not a perfect solution but since the testfile is not meant to be seen by any1 i'll take it for now... Thank's everybody who brainstormed with me for this 45 mins.

Pavlos Panteliadis
  • 1,495
  • 1
  • 15
  • 25
0

Do !(line1 = s.nextLine()) != null, not empty, as it cannot read an empty line.

Slow Trout
  • 492
  • 3
  • 13
0

From Scanner#nextLine:

Throws:
NoSuchElementException - if no line was found.

And you have this code:

while (s.hasNextLine()) {
    //checked if there's line to read
    String line1 = s.nextLine();
    if (line1.startsWith("Users")) {
        //not checked if there's line to read
        line1 = s.nextLine();
        //not checked here either
        while (!(line1 = s.nextLine()).isEmpty()) {
            String arr[] = line1.split(" ", 4);
            users.add(new User(arr[0],arr[1],arr[2],arr[3]));
        }
    }
    //similar in code below...
}

Make sure to validate there's a line to be read before using Scanner#nextLine. Handle the exceptions accordingly.

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
0

enter image description here

As you can see, this method throws NoSuchElementException when no line was found.

if (line1.startsWith("Lists")){
        line1 = s.nextLine(); // <=============== ?
        while (!(line1 = s.nextLine()).isEmpty()) { //exception here

How do you know that you have more lines there and in your comment line?

CarlosMorente
  • 775
  • 1
  • 7
  • 17
  • i'm not comparing. i'm assigning the value of s.nextline() to line1 to use inside the loop – Pavlos Panteliadis Apr 17 '15 at 16:12
  • Ooops sorry, mistake reading :P Anyway, how do you know that you've more lines? – CarlosMorente Apr 17 '15 at 16:14
  • with this --> !(line1 = s.nextLine()).isEmpty() <-- it assigns the value of s.nextLine to line1 and then i'm checking if line1 is empty. If it's not empty i proceed with the check (assuming the testfile is correct). The thing that bothers me is why this works in the first if statement for the Users and the copy pasted code throws the exception. It's mind blowing! – Pavlos Panteliadis Apr 17 '15 at 16:19
  • Are you really sure that it works in the other statement? If nextLine() don't found any line, it should throw a NoSuchElementException as you can see in the imagen from the API. – CarlosMorente Apr 17 '15 at 16:23
  • positive. i'm checking whether the line is empty or not every time before entering the while statement with this -->!(line1 = s.nextLine()).isEmpty()<-- – Pavlos Panteliadis Apr 17 '15 at 16:29
  • i know whether to change the line manually or not because if i encounter the said keywords i automatically have to check the line directly under the keywords for info. – Pavlos Panteliadis Apr 17 '15 at 16:30
  • But you're assigning firstly the s.nextLine() return value to line1. I mean: if it should fail, you will check it after the fail. Why don't you use hasNextLine()? – CarlosMorente Apr 17 '15 at 16:31
  • what is also bugging me is that i went in the testfile and erased the lines under Users and Lists respectively. When i erased the lines under the users meaning no Users the code had no problem identify the empty line and went through to check the Lists. But when i erased the info under List i got the exception in a simple System.out.println(s.nextLine()). Why i'm getting an exception in the 2nd if but not in the first! it's driving me nuts really! P.S. thank you for your time so far. – Pavlos Panteliadis Apr 17 '15 at 16:35
  • Have you did a debug? Maybe it never enters into the first statement. – CarlosMorente Apr 17 '15 at 16:41
  • In addition, if you want 2 times a next line, you should ask it twice, not once as you're doing. – CarlosMorente Apr 17 '15 at 16:42
  • it enters the first time and fails from the 2nd and on because there is no other line under it. – Pavlos Panteliadis Apr 17 '15 at 16:46
  • And why don't you do `while(s.hasNextLine())` instead of doing this? – CarlosMorente Apr 17 '15 at 16:56