0

The Java program for my school work gives me an error:

Welcome to Surinam Airlines - We may get you there!

We have 6 seats available for flight JAVA123.

How many seats do you want to book? 3

Enter passenger #1's name: Taylor Swift
Enter passenger #1's food option
(V = vegetarian, N = no preference, H = Halal): V
Enter passenger #1's class (1 = first, 2 = business, 3 = economy): 1
Exception in thread "main" java.util.NoSuchElementException: No line found
        at java.util.Scanner.nextLine(Unknown source)
        at Passenger.enterPassenger(Passenger.java:64)
        at RunAirLine.main(RunAirLine.java:23)

It seems to have something to do with the object not being instantiated though I can't quite figure out why. Does anyone know what's wrong?

import java.util.*;

public class RunAirLine {

  private static Passenger seatArray[][] = new Passenger[2][3]; // declares new
                                                                // array of
                                                                // Passengers
  static Scanner kb = new Scanner(System.in);

  public static void main(String[] args) {
    System.out.println("Welcome to Surinam Airlines – We may get you there!");
    System.out.println();

    int seats = 6; // available seats
    while (seats > 0) {
      System.out.println("We have " + seats
          + " seats available for flight JAVA123.");
      System.out.println();
      System.out.print("How many seats do you want to book? ");
      int n = kb.nextInt();
      System.out.println();

      for (int i = 0; i < n; i++) {
        int x = emptySeat()[0];
        int y = emptySeat()[1];
        // retrieves info from emptySeat() function
        seatArray[x][y] = new Passenger();
        seatArray[x][y].enterPassenger(7 - seats); // gives the method the nth
                                                   // passenger number
        seats--; // takes away 1 from the available seats
      }
      System.out.println();
    }
    System.out.println("No seats available.");
    System.out.println();
    System.out.println("Flight manifest:");
    System.out.println();
    for (int y = 0; y < 3; y++) { // prints out the list of flyers
      for (int x = 0; x < 2; x++) {
        System.out.println(seatArray[x][y].getSeat() + " "
            + seatArray[x][y].printPassengerCode());
      }
    }
    kb.close();
  }

  public static int[] emptySeat() {
    for (int y = 0; y < 3; y++) {// finds the next empty seat
      for (int x = 0; x < 2; x++) {
        if (seatArray[x][y] == null || seatArray[x][y].getSeat().equals("")) {
          // if the spot hasn't been declared yet or is empty
          return new int[] { x, y };
        }
      }
    }
    return null; // if none found then return null
  }
}

Passenger.java

import java.util.*;

public class Passenger {
  private String name;
  private String seat;
  private char foodOption;
  private int seatClass;

  // reduces some redundancy
  private String classStr;
  private String prefStr;

  public Passenger() { // constructors
    name = "";
    seat = "";
    foodOption = ' ';
    seatClass = -1;
  }

  public Passenger(String n, String s, char f, int sc) { // assigns values
                                                         // according to input
    name = n;
    seat = s;
    foodOption = f;
    seatClass = sc;
  }

  // get and set methods
  public void setName(String n) {
    name = n;
  }

  public void setSeat(String s) {
    seat = s;
  }

  public void setFoodOption(char f) {
    foodOption = f;
  }

  public void setSeatClass(int sc) {
    seatClass = sc;
  }

  public String getName() {
    return name;
  }

  public String getSeat() {
    return seat;
  }

  public char getFoodOption() {
    return foodOption;
  }

  public int getSeatClass() {
    return seatClass;
  }

  // end of get and set methods

  public void enterPassenger(int i) {
    Scanner kb = new Scanner(System.in);
    // asks the important questions
    System.out.print("Enter passenger #" + i + "’s name: ");
    name = kb.nextLine();
    System.out.println("Enter passenger #" + i + "’s food option ");
    System.out.print("(V = vegetarian, N = no preference, H = Halal): ");
    foodOption = kb.nextLine().toUpperCase().charAt(0);
    System.out.print("Enter passenger #" + i
        + "’s class (1 = first, 2 = business, 3 = economy): ");
    seatClass = kb.nextInt();

    System.out.println();
    char seatChar = 'A'; // calculates the seat number
    if (i % 2 == 0)
      seatChar = 'B';
    seat = Integer.toString(i / 2 + i % 2) + seatChar;

    classStr = "Economy Class"; // transfers the class choice int into string
    switch (seatClass) {
    case 1:
      classStr = "First Class";
      break;
    case 2:
      classStr = "Business Class";
      break;
    }

    prefStr = "No preference"; // transfers the preference char into string
    switch (foodOption) {
    case 'V':
      prefStr = "Vegetarian";
      break;
    case 'H':
      prefStr = "Halal";
      break;
    }

    System.out.println("Done – Seat " + seat + " booked");
    System.out
        .println("-------------------------------------------------------------------");
    System.out.println(name + "(" + classStr + " - Seat " + seat + ") - "
        + prefStr);
    System.out
        .println("-------------------------------------------------------------------");
    kb.close();
  }

  public void printTicketStub() {
    char initial = name.split(" ")[0].toUpperCase().charAt(0); // splits name
                                                               // into first
                                                               // name and
                                                               // second name
    System.out.println(initial + ". " + name.split(" ")[1] + "(" + classStr
        + " - Seat " + seat + ") - " + prefStr);
  }

  public String printPassengerCode() { // forms the code as required
    return seatClass + name.toUpperCase().substring(name.length() - 4)
        + foodOption;
  }
}
durron597
  • 30,764
  • 16
  • 92
  • 150
CowNorris
  • 47
  • 1
  • 9
  • Please can you indicate line 64 of Passenger.java? – Andy Turner Jul 10 '15 at 20:22
  • @AndyTurner name = kb.nextLine(); – CowNorris Jul 10 '15 at 20:23
  • Are you 100% certain about that? I ask because the next few lines are executed (you are asked about food option and class before the exception occurs). Have you changed your code since posting the stack trace? – Andy Turner Jul 10 '15 at 20:26
  • @AndyTurner I cleaned up the spacing when I turned the screenshot and pastebin links into actual code, which probably changed the line numbers. See the edit history. – durron597 Jul 10 '15 at 20:27

1 Answers1

4

You have two problems:

  1. You create a Scanner for System.in twice. You should only do this once. I have commented out the one you create in Passenger.java, and changed the reference to the one in RunAirLine.java:

    public void enterPassenger(int i) {
    //        Scanner kb = new Scanner(System.in);
        // asks the important questions
        System.out.print("Enter passenger #" + i + "’s name: ");
        name = RunAirLine.kb.nextLine();
        System.out.println("Enter passenger #" + i + "’s food option ");
        System.out.print("(V = vegetarian, N = no preference, H = Halal): ");
        foodOption = RunAirLine.kb.nextLine().toUpperCase().charAt(0);
        System.out.print("Enter passenger #" + i
            + "’s class (1 = first, 2 = business, 3 = economy): ");
        seatClass = RunAirLine.kb.nextInt();
        RunAirLine.kb.nextLine();
    
  2. Every time you do nextInt(), it doesn't take the new line off the Scanner's reading, which messes stuff up. If you want nextInt() to be on it's own line, you should throw a dummy RunAirLine.kb.nextLine(); after the nextInt() call. This needs to be done twice, once in the code I've fixed above, and once in your RunAirLine.class:

    System.out.print("How many seats do you want to book? ");
    int n = kb.nextInt();
    kb.nextLine();
    System.out.println();
    

Further reading on Why you shouldn't have multiple Scanners. the tl;dr of is that closing System.in closes the stream forever.

Community
  • 1
  • 1
durron597
  • 30,764
  • 16
  • 92
  • 150
  • as another fix, I tried calling kb.close() on the Scanner in RunAirLines before the call to create his passengers. Why does this not work? Why can't we create a second Scanner for System.in, even if we close the first one? – BoDidely Jul 10 '15 at 20:37
  • Thanks, I didn't realize close() closed the actual stream forever – BoDidely Jul 10 '15 at 20:41