anthony
anthony

Reputation: 401

Java. Problems reading an input

I am doing a homework assignment that deals with classes and objects. In it, I have an Address class, Letter class, and PostOffice class that when calling PostOffice, takes an input file and scans through it, printing basically everything in the input file the way it should appear on a letter (to: bla, from: bla, postage amount, to and from address, etc.)

i get an error that reads:

Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1516)
at PostOffice.readLetters(PostOffice.java:33)
at PostOffice.main(PostOffice.java:14)

and I dont really understand why....

here is my post office class:

import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

public class PostOffice {

private final int MAX = 1000;
private Letter [] letterArray = new Letter[MAX];
private int count;

public static void main(String [] args) {
    PostOffice postOffice = new PostOffice();
    postOffice.readLetters("letters.in");
    postOffice.sortLetters();
    postOffice.printLetters();
}

public PostOffice() {
    Letter [] myLetters = letterArray;
    this.count = 0;
}

public void readLetters(String filename) {
    String toName, toStreet, toCity, toState, toZip;
    String fromName, fromStreet, fromCity, fromState, fromZip, temp; //, weight;
    double weight;
    int index;
    Scanner s = new Scanner(filename);
    if (s != null) {
        while(s.hasNext()){
            toName = s.nextLine();
            toStreet = s.nextLine();
            temp = s.nextLine();
            index = temp.indexOf(",");
            toCity = temp.substring (0, index);
            index = index + 2;
            toState = temp.substring (index, index + 2);
            toZip = temp.substring (index);
            fromName = s.nextLine();
            fromStreet = s.nextLine();
            temp = s.nextLine();
            index = temp.indexOf(",");
            fromCity = temp.substring (0, index);
            index = index + 2;
            fromState = temp.substring (index, index + 2);
            fromZip = temp.substring (index);
            String var = s.nextLine();
            weight = Double.parseDouble(var);
            //weight = s.nextLine();
            Letter l = new Letter(toName, toStreet, toCity, toState, toZip, fromName, fromStreet, fromCity, fromState, fromZip, weight);
            this.count += 1;
            this.letterArray[count - 1] = l;
        }
    }
    s.close();
}

public static void sortLetters() {
//call sortSearchUtil This method should call the compareTo method provided by the Letter class to sort.  
//You may use any sorting routine you wish (see SortSearchUtil.java)
}

public static void printLetters() {
//call tostring of letter class. print the count of Letters followed by the total postage followed 
//by each Letter (make sure you use the toString method provided by the Address and Letter classes for this)
}

}

my letter class:

    public class Letter extends PostOffice implements Comparable<Letter> {
private static final double POSTAGE_RATE = 0.46;
private String fromName;
private Address fromAddr;
private String toName;
private Address toAddr;
private double weight;


    public Letter (String fromName, String fromStreet, String fromCity, String fromState,       String fromZip, String toName, 
String toStreet, String toCity, String toState, String toZip, double weight) {
this.fromName = fromName;
this.fromAddr = new Address(fromStreet, fromCity, fromState, fromZip);
this.toName = toName;
this.toAddr = new Address(toStreet, toCity, toState, toZip);
this.weight = weight;   
}

public String toString() {
String result;
result = String.format("from: %s\t\t\t%5.2f\n%s", fromName, getPostage(weight), fromAddr);
result = result + String.format("\t\t To: %s\n\t\t%s", toName, toAddr);
return result;
}

    public int compareTo(Letter that) {
int value;
value = this.toAddr.getZip().compareTo(that.toAddr.getZip());
return value;
}


public static double getPostage(double weight) {
double workWeight;
workWeight = weight + 0.999;
workWeight = (int)workWeight;   
return workWeight * POSTAGE_RATE;
    } 
}

and my address class:

import java.awt.*;
import java.util.*;

public class Address {
private String street;
private String city;
private String state;
private String zip;

    public Address (String street, String city, String state, String zip) {
    this.street = street;
    this.city = city;
    this.state = state;
    this.zip = zip;
    }

    public String getStreet() {
    return street;
    }

    public void setStreet(String street) {
    this.street = street;
    }

    public String getCity() {
    return city;
    }

    public void setCity(String city) {
    this.city = city;
    }

    public String getState() {
    return state;
    }

    public void setState(String state) {
    this.state = state;
    }

    public String getZip() {
    return zip;
    }

    public void setZip(String zip) {
    this.zip = zip;
    }

    public String toString() {
    String result;
    result = String.format("%s\n%s, %s %s", street, city, state, zip);
    return result;  
    }
}

and this is the content of the text file

Stu Steiner (NEW LINE)
123 Slacker Lane (NEW LINE)
Slackerville, IL  09035 (NEW LINE)
Tom Capaul(NEW LINE)
999 Computer Nerd Court (NEW LINE)
Dweebsville, NC  28804-1359 (NEW LINE)
0.50 (NEW LINE)
Tom Capaul (NEW LINE)
999 Computer Nerd Court (NEW LINE)
Dweebsville, NC  28804-1359 (NEW LINE)
Chris Peters (NEW LINE)
123 Some St. (NEW LINE)
Anytown, CA  92111-0389 (NEW LINE)
1.55 (NEW LINE)

Everything compiles, I just need it to output like this:

----------------------------------------------------------------------------

From: From value                                              Postage value
From Address value (be sure and use Address toString)

                    To: To value
                    To Address value (be sure and use Address toString)

----------------------------------------------------------------------------

Upvotes: 0

Views: 1402

Answers (4)

Adel Boutros
Adel Boutros

Reputation: 10295

You do s.readline() many times inside 1 iteration of while loop. This is why you're getting the error.

You need to call readLine() only once inside your while loop

Example in your code:

while(s.hasNext()){
        toName = s.nextLine();
        toStreet = s.nextLine();
        temp = s.nextLine();
        // ...
    }

These are 3 calls to nextLine, how are you sure there are still lines?

SOLUTION:

put an if statement before every s.nextLine() except the first one. Example:

while(s.hasNext()){
     toName = s.nextLine();
     if (s.hasNext()) {
         toStreet = s.nextLine();
     }
     if (s.hasNext()) {
         temp = s.nextLine();
     }
     // ...
}

Upvotes: 4

Bhesh Gurung
Bhesh Gurung

Reputation: 51030

The problem is the mistmatch (hasNext() and nextLine()).

With nextLine() you should use hasNextLine(). This is probably the combination you need as you seem to read it line by line.

e.g. looking at your text file something as follows should but modification must be made in case if the text file is not always well formed:

while(s.hasNextLine()) { // check if there is next line
    String toName = s.nextLine();
    String toAddrLine1 = s.nextLine();
    String toAddrLine2 = s.nextLine();
    String fromName = s.nextLine();
    String fromAddrLine1 = s.nextLine();
    String fromAddrLine2 = s.nextLine();
    String postageValueStr = s.nextLine();

    //do further processing down here

While hasNext() should be used in combination with next().

Please, go through the Scanner doc.

Upvotes: 0

tim
tim

Reputation: 2039

Your suspicion was right: you are not opening up a file but just passing the string "letter.in" to the scanner. The correct code would be:

    Scanner s = null;
    try {
        s = new Scanner(new File(filename));
    } catch (FileNotFoundException ex) {
        Logger.getLogger(PostOffice.class.getName()).log(Level.SEVERE, null, ex);
    }
    if (s != null) {
         ....
    }

Your program still will not print anything as the printLetters() method is not implemented, but it will not crash anymore (at least not if the file always has a multiple of 7 lines). The input format is not very well chosen, but as it is homework I guess it was not really your choice. to make the code at least a little bit less error prone you could ask before every nextLine if there actually is a next line (this is not a good solution, but one that is done without much work).

Upvotes: 0

user800014
user800014

Reputation:

Probably you missed to test if you have the next line:

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Scanner.html#hasNext%28%29

Upvotes: 2

Related Questions