0

I have these two classes: Contact and Phonebook:

public class Contact implements Comparable<Contact> {
    private String name;
    String[] numbers;
    private final int NUMBER_LIMIT = 5;
}

public class Phonebook {
    private final int CONTACT_LIMIT = 250;
    Contact[] contacts;
}

I want to transform the data from both classes to String and save it to a text file. For this purpose, I wrote the following functions:

public class Contact {

    @Override
    public String toString() {
        StringBuilder str = new StringBuilder();
        int len = numbers.length;

        str.append(name);
        str.append(System.lineSeparator());
        str.append(len);
        str.append(System.lineSeparator());

        for (int i = 0; i < len; i++) {
            str.append(numbers[i]);
            if (i != len - 1)
                str.append(System.lineSeparator());
        }

        return str.toString();
    }
}

public class Phonebook {
    @Override
    public String toString() {
        StringBuilder str = new StringBuilder();

        for (int i = 0, n = contacts.length; i < n; i++) {
            str.append(contacts[i].toString());
            if (i != n - 1) str.append(System.lineSeparator());
        }

        return str.toString();
    }

    public static boolean saveAsTextFile(Phonebook phonebook, String path) {
        boolean saved = true;
        PrintWriter toFile = null;
        try {
            toFile = new PrintWriter(new FileOutputStream(path));
            toFile.println(phonebook.toString());
        }
        catch (FileNotFoundException e) {
            saved = false;
        }
        finally {
            toFile.close();
        }
        return saved;
    }
}

The next step is reading the contents from an existing text file and recreating a Phonebook object. The text file has the following format:

Contact name (String)
Number of phone numbers (int)
Phonenumber(s) (String)

There can be more than 1 contact in the text file. So far I have this function for creating a contact from a string:

public static Contact valueOf(String s) throws InvalidFormatException {
        String lineSeparator = System.lineSeparator();
        String[] chunks = s.split(lineSeparator);
        int len = chunks.length;

        if (len < 2) throw new InvalidFormatException();

        //System.out.println(Arrays.toString(chunks));
        String name = chunks[0];
        String[] numbers = new String[Integer.parseInt(chunks[1])];
        for (int i = 2; i < len; i++)
            numbers[i - 2] = chunks[i];

        Contact contact = null;

        try {
            contact = new Contact(name, numbers);
            return contact;
        }
        catch (Exception e) {
            throw new InvalidFormatException();
        }
    }

And this one for creating the Phonebook(It is a work in progress):

public static Phonebook loadFromTextFile(String path) throws FileNotFoundException, InvalidFormatException {
    Scanner inputStream = new Scanner(new FileInputStream(path));
    ArrayList<String> contactInfo = new ArrayList<String>();
    int ctr = 0;
    int numContacts;
    String contactString = "";
    Contact contact = null;

    while (inputStream.hasNextLine()) {
        contactInfo.add(inputStream.nextLine());
        if (ctr == 1) {
            numContacts = Integer.parseInt(contactInfo.get(ctr));
            for (int j = 0; j < numContacts; j++) {
                contactInfo.add(inputStream.nextLine());
            }
            System.out.println("contactString inside while loop:");
            contactString = String.join(System.lineSeparator(), contactInfo);
            System.out.println(contactString);
            contact = Contact.valueOf(contactString);
            contactInfo.clear();
            System.out.println("contact inside while loop:");
            System.out.println(contact);
            ctr = 0;
        }
        ctr++;
    }

The problem I'm having is that this function works only for a single contact in the file. If there are multiple, it does not work. What am I doing wrong? My logic is this:

  • Read line from text file and store it in ArrayList

  • If you read the number of contacts:

    • Iterate over the number of contacts, reading every line and storing it in ArrayList
  • When done, transform the contents of ArrayList to String, move it to contactString and call Contact.valueOf(String s). When I get this working, store the resulting Contact in a Contact[].

  • Empty ArrayList and start again.

  • Repeat until EOF

I cannot figure out what is causing the problem. Any help is appreciated.

Note : If it matters, this is a homework assignment.

EDIT: Sample .txt file:

John Doe
3
3124354353
1234324534
5768324242
Alice
1
0547623424
Bob
2
7863257643
3128443552

1 Answer 1

2

The problem seems to be the ctr variable.
It is initialized to 0

int ctr = 0;

incremented in the while loop

ctr++;

and there is an if statement in the while loop

if (ctr == 1) {

In there is also set to 0

So the while loop will execute twice, adding 2 lines to contactInfo then add another numOfContacts lines to contactInfo and then try to create a single contact.

Based on how the example text file looks like I would recommend this simpler version without the ctr variable

while (inputStream.hasNextLine()) {
    contactInfo.add(inputStream.nextLine());
    int numContacts = Integer.parseInt(inputStream.nextLine());

    for (int j = 0; j < numContacts; j++) {
        contactInfo.add(inputStream.nextLine());
    }
    System.out.println("contactString inside while loop:");
    String contactString = String.join(System.lineSeparator(), contactInfo);
    System.out.println(contactString);

    contactInfo.clear();
    System.out.println("contact inside while loop:");
}

Note that I defined contactString and numContacts in the loop as there is not reason for them to exist outside

Sign up to request clarification or add additional context in comments.

4 Comments

won't the while loop execute until end of file? ctr is not part of its condition
actually, I am always skipping the second name this way. After the if statement, ctr is again 1, which makes it skip the contact name before the numOfContacts. I should only change it to ctr=-1
Actually it may loop beyond. You are not checking hasNextLine in the for loop inside the while loop. I believe that the way you use ctr results in getting only one Contact. It'll be great if you post an example of the text file for that
it is guaranteed that there will be at least numContacts lines after the actual numContacts, because of the way it is calculated

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.