Margarita Kattsyna
Margarita Kattsyna

Reputation: 5

How to fix NoSuchElementException?

I have tried to load contacts from a file contacts.txt.

Issue

This program was working and now it is not.

Exception in thread "main" java.util.NoSuchElementException
        at java.base/java.util.Scanner.throwFor(Scanner.java:937)
        at java.base/java.util.Scanner.next(Scanner.java:1478)
        at Main.loadContacts(Main.java:28)
        at Main.main(Main.java:14)`

Code

There are two more classes in the models (Contact, ContactManager) and a text file (contact.txt).

This is class Main.

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.text.ParseException;
import java.util.Scanner;

import models.Contact;
import models.ContactManager;

class Main {
   
    static ContactManager manager = new ContactManager();
    public static void main(String[] args) {
        try {
     loadContacts("contacts.txt"); 
     System.out.println("CONTACTS LOADED\n\n");
     System.out.println(manager);
     manageContact();
        } catch (FileNotFoundException e) {
            System.out.println(e.getMessage());
        }
        }
 
public static void loadContacts(String fileName) throws FileNotFoundException {
        FileInputStream fis = new FileInputStream(fileName);
        Scanner scan = new Scanner(fis);
        while (scan.hasNextLine()) {
            try {
            Contact contact = new Contact(scan.next(), scan.next(), scan.next());
            manager.addContact(contact);
            } catch (ParseException e) {
                System.out.println(e.getMessage());
            }
        }
        scan.close();
     } 
     
     public static void manageContact() {
        Scanner scan = new Scanner(System.in);
        while (true) {
            System.out.println("Would you like to a) add another contact b) remove a contact c) exit"); 
            String response = scan.nextLine();
            if (response.equals("a")) {
                System.out.println("\tName: ");
                String name = scan.nextLine();
                System.out.println("\tPhone number: ");
                String phoneNumber = scan.nextLine();
                System.out.println("\tBirth Date: ");
                String birthDate = scan.nextLine();
                if (name.isBlank() || phoneNumber.isBlank() || phoneNumber.length() < 5) {
                    System.out.println("\nThe input is not valid.");
                } else { 
                try {
                manager.addContact(new Contact(name, phoneNumber, birthDate));
                } catch (ParseException e) {
                    System.out.println(e.getMessage());
                } finally {
                System.out.println("\n\nUPDATED CONTACTS\n\n" + manager);
            }
        }
        } else if (response.equals("b")) {
            System.out.println("Who would you like to remove?");
            manager.removeContact(scan.nextLine());
            System.out.println("\n\nUPDATED CONTACTS\n\n" + manager);
        } else {
            break;
        }
     }
     scan.close();
    }
}

Question

I can not find the mistake. How can I fix this unchecked exception? If I have to throw NoSuchElementException, where I have to add this?

Upvotes: 0

Views: 43

Answers (1)

hc_dev
hc_dev

Reputation: 9418

Assumption of the file input structure

Assume your input file contacts.txt is structured as follows:

  • one contact per line
  • each line contains 3 parts for the contact, parts are separated (e.g. by comma)
  • lines end with \n (new line) or \r\n (line feed, new line)

Please always provide your inputs (link), even when just given as rough simplified example:

Chet Baker, Amsterdam, Netherlands
George Gershwin, Hollywood, USA

Issue

Java Scanner's method next() reads the next token. If there is no next token, the NoSuchElementException is thrown.

It is safer to use nextLine() and then split the line. This gives you the chance to print and debug the line read.

See Understanding Scanner's nextLine(), next(), and nextInt() methods.

Solution with nextLine and split

public static void loadContacts(String fileName) throws FileNotFoundException {
  FileInputStream fis = new FileInputStream(fileName);
  Scanner scan = new Scanner(fis);
  while (scan.hasNextLine()) {
    try {
      // this was the original line that caused the NoSuchElement exception
      //Contact contact = new Contact(scan.next(), scan.next(), scan.next());
      String line = scan.nextLine();  // read the line as whole
      System.out.println(line);  // control what is read
      String[] parts = line.split(",");  // split the line, e.g. by comma
      if (parts.length < 3) {  // require at least 3 parts
        break;  // then stop this iteration and try next line
      }
      Contact contact = new Contact(part[0], part[1], part[2]);
      manager.addContact(contact);
    } catch (ParseException e) {
      System.out.println(e.getMessage());
    }
  }
  scan.close();
} 

Upvotes: 0

Related Questions