Create and Use Phone Book

Overview

The main function, phonebook, can be called either with no arguments, or with one argument, which is the key of an entry that exists in the phone book. The function first determines the folder to use for the phone book file.

If no phone book file exists, it creates one by constructing a java.io.FileOutputStream object, and then closing the output stream. Next, it creates a data dictionary by constructing an object of java.util.Properties, which is a subclass of java.util.Hashtable, for storing key/value pairs in a hash table. For the phonebook program, the key is a name, and the value is one or more telephone numbers.

The phonebook function creates and opens an input stream for reading by constructing a java.io.FileInputStream object. It calls load on that object to load the hash table contents, if it exists. If the user passed the key to an entry to look up, it looks up the entry by calling pb_lookup, which finds and displays it. Then, the phonebook function returns.

If phonebook was called without the name argument, it then displays a textual menu of the available phone book actions:

The menu also has a selection to exit the program. The function uses MATLAB® functions to display the menu and to input the user selection.

The phonebook function iterates accepting user selections and performing the requested phone book action until the user selects the menu entry to exit. The phonebook function then opens an output stream for the file by constructing a java.io.FileOutputStream object. It calls save on the object to write the current data dictionary to the phone book file. It finally closes the output stream and returns.

Description of Function phonebook

The major tasks performed by phonebook are:

  1. Determine the data folder and full file name.

    The first statement assigns the phone book file name, 'myphonebook', to the variable pbname. If the phonebook program is running on a Windows® system, it calls the java.lang.System static method getProperty to find the location of the data dictionary. This is set to the user's current working folder. Otherwise, it uses MATLAB function getenv to determine the location, using the system variable HOME, which you can define beforehand to anything you like. It then assigns to pbname the full path, consisting of the data folder and file name 'myphonebook'.

    function phonebook(varargin)
    pbname = 'myphonebook'; % name of data dictionary
    if ispc
       datadir = char(java.lang.System.getProperty('user.dir'));
    else
       datadir = getenv('HOME');
    end
    pbname = fullfile(datadir, pbname);
  2. If needed, create a file output stream.

    If the phonebook file does not exist, phonebook asks the user whether to create a new one. If the user answers y, phonebook creates a phone book by constructing a FileOutputStream object. In the try clause of a try/catch block, the argument pbname passed to the FileOutputStream constructor is the full name of the file that the constructor creates and opens. The next statement closes the file by calling close on the FileOutputStream object FOS. If the output stream constructor fails, the catch statement prints a message and terminates the program.

    if ~exist(pbname)
       disp(sprintf('Data file %s does not exist.', pbname))
       r = input('Create a new phone book (y/n)?','s');
       if r == 'y',
          try
             FOS = java.io.FileOutputStream(pbname);
             FOS.close
          catch
             error(sprintf('Failed to create %s', pbname))
          end
       else
          return
       end
    end
  3. Create a hash table.

    The example constructs a java.util.Properties object to serve as the hash table for the data dictionary.

    pb_htable = java.util.Properties;
  4. Create a file input stream.

    In a try block, the example invokes a FileInputStream constructor with the name of the phone book file, assigning the object to FIS. If the call fails, the catch statement displays an error message and terminates the program.

    try
       FIS = java.io.FileInputStream(pbname);
    catch
       error(sprintf('Failed to open %s for reading.', pbname))
    end
  5. Load the phone book keys and close the file input stream.

    The example calls load on the FileInputStream object FIS, to load the phone book keys and their values (if any) into the hash table. It then closes the file input stream.

    pb_htable.load(FIS)
    FIS.close
  6. Display the Action menu and get the user's selection.

    Within a while loop, several disp statements display a menu of actions that the user can perform on the phone book. Then, an input statement requests the user's typed selection.

    while 1
       disp ' '
       disp ' Phonebook Menu:'
       disp ' '
       disp ' 1. Look up a phone number'
       disp ' 2. Add an entry to the phone book'
       disp ' 3. Remove an entry from the phone book'
       disp ' 4. Change the contents of an entry in the phone book'
       disp ' 5. Display entire contents of the phone book'
       disp ' 6. Exit this program'
       disp ' '
       s = input('Please type the number for a menu selection: ','s');
  7. Invoke the function to perform a phone book action

    Still within the while loop, a switch statement provides a case to handle each user selection s. Each of the first five cases invokes the function to perform a phone book action.

    switch s

    Case 1 prompts for a name that is a key to an entry. It calls isempty to determine whether the user has entered a name. If a name has not been entered, it calls disp to display an error message. If a name has been input, it passes it to pb_lookup. The pb_lookup routine looks up the entry and, if it finds it, displays the entry contents.

    case '1',
       name = input('Enter name to look up: ','s');
       if isempty(name)
          disp 'No name entered'
       else
          pb_lookup(pb_htable, name)
       end

    Case 2 calls pb_add, which prompts the user for a new entry and then adds it to the phone book.

    case '2',
       pb_add(pb_htable)

    Case 3 uses input to prompt for the name of an entry to remove. If a name has not been entered, it calls disp to display an error message. If a name has been entered, it passes it to pb_remove.

    case '3',
       name = input('Enter name of entry to remove: ', 's');
       if isempty(name)
          disp 'No name entered'
       else
          pb_remove(pb_htable, name)
       end

    Case 4 uses input to prompt for the name of an entry to change. If a name has not been entered, it calls disp to display an error message. If a name has been entered, it passes it to pb_change.

    case '4',
       name = input('Enter name of entry to change: ', 's');
       if isempty(name)
          disp 'No name entered'
       else
          pb_change(pb_htable, name)
    end

    Case 5 calls pb_listall to display all entries.

    case '5',
       pb_listall(pb_htable)
  8. Exit by creating an output stream and saving the phone book.

    If the user has selected case 6 to exit the program, a try statement calls the constructor for a FileOuputStream object, passing it the name of the phone book. If the constructor fails, the catch statement displays an error message.

    If the object is created, the next statement saves the phone book data by calling save on the Properties object pb_htable, passing the FileOutputStream object FOS and a descriptive header string. It then calls close on the FileOutputStream object, and returns.

    case '6',
       try
          FOS = java.io.FileOutputStream(pbname);
       catch
          error(sprintf('Failed to open %s for writing.',pbname))
       end
       pb_htable.save(FOS,'Data file for phonebook program')
       FOS.close;
       return
    otherwise
       disp 'That selection is not on the menu.'
    end
    
    end % switch

Description of Function pb_lookup

Arguments passed to pb_lookup are the Properties object pb_htable and the name key for the requested entry. The pb_lookup function first calls get on pb_htable with the name key, on which support function pb_keyfilter is called to change spaces to underscores. The get method returns the entry (or null, if the entry is not found) to variable entry. get takes an argument of type java.lang.Object and also returns an argument of that type. In this invocation, the key passed to get and the entry returned from it are actually character arrays.

pb_lookup then calls isempty to determine whether entry is null. If it is, it uses disp to display a message stating that the name was not found. If entry is not null, it calls pb_display to display the entry.

function pb_lookup(pb_htable,name)
entry = pb_htable.get(pb_keyfilter(name));
if isempty(entry),
   disp(sprintf('The name %s is not in the phone book',name))
else
   pb_display(entry)
end

Description of Function pb_add

  1. Input the entry to add.

    The pb_add function takes one argument, the Properties object pb_htable. pb_add uses disp to prompt for an entry. Using the up arrow (^) character as a line delimiter, input inputs a name to the variable entry. Then, within a while loop, it uses input to get another line of the entry into variable line. If the line is empty, indicating that the user has finished the entry, the code breaks out of the while loop. If the line is not empty, the else statement appends line to entry and then appends the line delimiter. At the end, the strcmp checks the possibility that no input was entered and, if that is the case, returns.

    function pb_add(pb_htable)
    disp 'Type the name for the new entry, followed by Enter.'
    disp 'Then, type the phone number(s), one per line.'
    disp 'To complete the entry, type an extra Enter.'
    name = input(':: ','s');
    entry = [name '^'];
    while 1
       line = input(':: ','s');
       if isempty(line)
          break
       else
          entry = [entry line '^'];
       end
    end
    if strcmp(entry, '^')
       disp 'No name entered'
       return
    end
  2. Add the entry to the phone book.

    After the input has completed, pb_add calls put on pb_htable with the hash key name (on which pb_keyfilter is called to change spaces to underscores) and entry. It then displays a message that the entry has been added.

    pb_htable.put(pb_keyfilter(name),entry)
    disp ' '
    disp(sprintf('%s has been added to the phone book.', name))

Description of Function pb_remove

  1. Look for the key in the phone book.

    Arguments passed to pb_remove are the Properties object pb_htable and the name key for the entry to remove. The pb_remove function calls containsKey on pb_htable with the name key, on which support function pb_keyfilter is called to change spaces to underscores. If name is not in the phone book, disp displays a message and the function returns.

    function pb_remove(pb_htable,name)
    if ~pb_htable.containsKey(pb_keyfilter(name))
       disp(sprintf('The name %s is not in the phone book',name))
       return
    end
  2. Ask for confirmation and if given, remove the key.

    If the key is in the hash table, pb_remove asks for user confirmation. If the user confirms the removal by entering y, pb_remove calls remove on pb_htable with the (filtered) name key, and displays a message that the entry has been removed. If the user enters n, the removal is not performed and disp displays a message that the removal has not been performed.

    r = input(sprintf('Remove entry %s (y/n)? ',name), 's');
    if r == 'y'
       pb_htable.remove(pb_keyfilter(name))
       disp(sprintf('%s has been removed from the phone book',name))
    else
       disp(sprintf('%s has not been removed',name))
    end

Description of Function pb_change

  1. Find the entry to change, and confirm.

    Arguments passed to pb_change are the Properties object pb_htable and the name key for the requested entry. The pb_change function calls get on pb_htable with the name key, on which pb_keyfilter is called to change spaces to underscores. The get method returns the entry (or null, if the entry is not found) to variable entry. pb_change calls isempty to determine whether the entry is empty. If the entry is empty, pb_change displays a message that the name is added to the phone book, and allows the user to enter the phone number for the entry.

    If the entry is found, in the else clause, pb_change calls pb_display to display the entry. It then uses input to ask the user to confirm the replacement. If the user enters anything other than y, the function returns.

    function pb_change(pb_htable,name)
    entry = pb_htable.get(pb_keyfilter(name));
    if isempty(entry)
       disp(sprintf('The name %s is not in the phone book', name))
       return
    else
       pb_display(entry)
       r = input('Replace phone numbers in this entry (y/n)? ','s');
       if r ~= 'y'
          return
       end
    end
  2. Input new phone numbers and change the phone book entry.

    pb_change uses disp to display a prompt for new phone numbers. Then, pb_change inputs data into variable entry, with the same statements described in Description of Function pb_lookup.

    Then, to replace the existing entry with the new one, pb_change calls put on pb_htable with the (filtered) key name and the new entry. It then displays a message that the entry has been changed.

    disp 'Type in the new phone number(s), one per line.'
    disp 'To complete the entry, type an extra Enter.'
    disp(sprintf(':: %s', name))
    entry = [name '^'];
    while 1
       line = input(':: ','s');
       if isempty(line)
          break
       else
          entry = [entry line '^'];
       end
    end
    pb_htable.put(pb_keyfilter(name),entry)
    disp ' '
    disp(sprintf('The entry for %s has been changed', name))

Description of Function pb_listall

The pb_listall function takes one argument, the Properties object pb_htable. The function calls propertyNames on the pb_htable object to return to enum a java.util.Enumeration object, which supports convenient enumeration of all the keys. In a while loop, pb_listall calls hasMoreElements on enum, and if it returns true, pb_listall calls nextElement on enum to return the next key. It then calls pb_display to display the key and entry, which it retrieves by calling get on pb_htable with the key.

function pb_listall(pb_htable)
enum = pb_htable.propertyNames;
while enum.hasMoreElements
   key = enum.nextElement;
   pb_display(pb_htable.get(key))
end

Description of Function pb_display

The pb_display function takes an argument entry, which is a phone book entry. After displaying a horizontal line, pb_display calls MATLAB function strtok to extract the first line of the entry, up to the line delimiter (^), into t and the remainder into r. Then, within a while loop that terminates when t is empty, it displays the current line in t. Then it calls strtok to extract the next line from r, into t. When all lines have been displayed, pb_display indicates the end of the entry by displaying another horizontal line.

function pb_display(entry)
disp ' '
disp '-------------------------'
[t,r] = strtok(entry,'^');
while ~isempty(t)
   disp(sprintf(' %s',t))
   [t,r] = strtok(r,'^');
end
disp '-------------------------'

Description of Function pb_keyfilter

The pb_keyfilter function takes an argument key, which is a name used as a key in the hash table, and either filters it for storage or unfilters it for display. The filter, which replaces each space in the key with an underscore (_), makes the key usable with the methods of java.util.Properties.

function out = pb_keyfilter(key)
if ~isempty(strfind(key,' '))
   out = strrep(key,' ','_');
else
   out = strrep(key,'_',' ');
end

Running the phonebook Program

In this sample run, a user invokes phonebook with no arguments. The user selects menu action 5, which displays the two entries currently in the phone book (all entries are fictitious). Then, the user selects 2, to add an entry. After adding the entry, the user again selects 5, which displays the new entry along with the other two entries.

Phonebook Menu:
 
     1. Look up a phone number
     2. Add an entry to the phone book
     3. Remove an entry from the phone book
     4. Change the contents of an entry in the phone book
     5. Display entire contents of the phone book
     6. Exit this program
 
Please type the number for a menu selection: 5
 
-------------------------
 Sylvia Woodland
 (508) 111-3456
-------------------------
 
-------------------------
 Russell Reddy
 (617) 999-8765
-------------------------
 
Phonebook Menu:
 
     1. Look up a phone number
     2. Add an entry to the phone book
     3. Remove an entry from the phone book
     4. Change the contents of an entry in the phone book
     5. Display entire contents of the phone book
     6. Exit this program
 
Please type the number for a menu selection: 2
 
Type the name for the new entry, followed by Enter.
Then, type the phone number(s), one per line.
To complete the entry, type an extra Enter.
:: BriteLites Books
:: (781) 777-6868
:: 
 
BriteLites Books has been added to the phone book.

Phonebook Menu:
 
     1. Look up a phone number
     2. Add an entry to the phone book
     3. Remove an entry from the phone book
     4. Change the contents of an entry in the phone book
     5. Display entire contents of the phone book
     6. Exit this program
 
Please type the number for a menu selection: 5
 
-------------------------
 BriteLites Books
 (781) 777-6868
-------------------------

-------------------------
 Sylvia Woodland
 (508) 111-3456
-------------------------
 
-------------------------
 Russell Reddy
 (617) 999-8765
------------------------- 
Was this topic helpful?