CPhoneBook05
Home ] Up ]

 

//PhoneBook05.cpp

//    void sortByName(void); added 05
//Overload << for output     added 04
//Constructor CPhoneBook(ch) added 03


//include files
#include <iostream.h>
#include <string.h>
#include <stdlib.h>


//constants
int const MAX_LEN = 10;
int const MAX_COUNT = 10;
int const TEST_COUNT = 5;


//global variables
int masterKey = 1;


//test values
const char *testNames[] = 
  {"Bob", "Tom", "Ann", "Ron", "Ben", "Ken", "Rob",
   "Sam", "Don", "Dan", "Tim"};

const int MAX_NAMES = sizeof(testNames)/sizeof(testNames[0]);

const char *testPhones[] = 
  {"111-1111", "222-2222", "333-3333", "444-4444"};

const int MAX_PHONES = sizeof(testPhones)/sizeof(testPhones[0]);

const char *testGroups[] = 
  {"Group1", "Group2", "Group3", "Group4"};

const int MAX_GROUPS = sizeof(testGroups)/sizeof(testGroups[0]);


//CPhoneEntry
struct CPhoneEntry
  {
  char name[MAX_LEN+1];
  char phone[14+1];
  char group[10+1];
  int key;
  CPhoneEntry *next;
  };


//CPhoneBook
class CPhoneBook
  {
  private:
    CPhoneEntry *first;
    CPhoneEntry *last;
    int count;
  public:
    CPhoneBook(void);
    bool insertAtEnd(char name[], char phone[], char group[], int key);
    void display(void);
    void deleteAll(void);
    ~CPhoneBook(void);
    CPhoneBook(char ch);
    CPhoneEntry * searchByName(char name[]);
    void sortByName(void);
    bool insert(CPhoneEntry entry);
    bool modifyPhone(char name[], char newPhone[]);
    friend ostream & operator << (ostream &os, const CPhoneBook &list);
  };


//void CPhoneBook::sortByName(void)
//Algorithm
/*
  do the following
    check pairs from left to right and put them in order
    until no change in order of the list

  if first = last then exit function
  do the following
    set sorted = true
    p = first
    q = p->next
    while q <> null
      if name at p > name at q then
          swap records at p and q except the pointers
          sorted = false
          end if
      p = q or p = p->next
      q = q->next
      end while

    while not sorted
*/
void CPhoneBook::sortByName(void)
  {
  if (first == last) return;

  bool sorted;
  CPhoneEntry *p, *q;

  char tName[MAX_LEN+1];
  char tPhone[14+1];
  char tGroup[10+1];
  int  tKey;

  do 
    {
    sorted = true;
    p = first;
    q = p->next;
    while (q != NULL)
      {
      if ((strcmp(p->name, q->name)>0))
          {
          //swap records at p and q except the pointers
          strcpy(tName, p->name);
          strcpy(p->name, q->name);
          strcpy(q->name, tName);

          strcpy(tPhone, p->phone);
          strcpy(p->phone, q->phone);
          strcpy(q->phone, tPhone);

          strcpy(tGroup, p->group);
          strcpy(p->group, q->group);
          strcpy(q->group, tGroup);

          tKey = p->key;
          p->key = q->key;
          q->key = tKey;

          sorted = false;
          }
      p = q; // or p = p->next
      q = q->next;
      }

    }
    while (!sorted);
  }


void testSortByName(void)
  {
  //for (int i=0; i<TEST_COUNT; i++)
  //  {
    CPhoneBook b1('r');
    cout << "Original: " << b1;
    b1.sortByName();
    cout << "Sorted:   "<< b1;
  //  }
  }


ostream & operator << (ostream &dan, const CPhoneBook &list)
  {
  CPhoneEntry *p;
  dan << "Phonebook[" << list.count << "]\n";
  p = list.first;
  while (p != NULL)
    {
    dan << p->name << "  ";
    dan << p->phone << "   ";
    dan << p->group << "   ";
    dan << p->key << endl;
    p = p->next;
    };
  return dan;
  }


void testOperatorOutput(void)
  {
  //for (int i=0; i<TEST_COUNT; i++)
  //  {
    CPhoneBook b1('r'), b2('r');
    cout << b1 << b2;
  //  }
  }


//Constructor for CPhoneBook
//'r' random elements
//'u' distinct random elements
//'s' sorted list
//'i' enter from the keyboard
CPhoneBook::CPhoneBook(char ch)
  {
  cout << "constructor called\n";
  count = 0;
  first = NULL;
  last = NULL;

  if ('r' == ch)
      {
      char rName[MAX_LEN+1];
      char rPhone[14+1];
      char rGroup[10+1];
      int  rKey;

      for(int n = rand()%(MAX_COUNT+1); n>0; n--)
        {
        strcpy(rName, testNames[rand()%MAX_NAMES]);
        strcpy(rPhone, testPhones[rand()%MAX_PHONES]);
        strcpy(rGroup, testGroups[rand()%MAX_GROUPS]);
        rKey = masterKey++;
        insertAtEnd(rName, rPhone, rGroup, rKey);
        }
      }
  }


void testCPhoneBookConstructor(void)
  {
  for (int i=0; i<TEST_COUNT; i++)
    {
    CPhoneBook b1('r');
    b1.display();
    }
  }


CPhoneBook::~CPhoneBook(void)
  {
  cout << "destructor called\n";
  deleteAll();
  }


//void CPhoneBook::deleteAll(void)
//deletes all the nodes from the linked list
void CPhoneBook::deleteAll(void)
  {
  while (first != NULL)
    {
    last = first->next;
    delete first;
    first = last;
    }
  count = 0;
  }


void CPhoneBook::display(void)
  {
  CPhoneEntry *p;
  cout << "Phonebook[" << count << "]\n";
  p = first;
  while (p != NULL)
    {
    cout << p->name << endl;
    cout << p->phone << endl;
    cout << p->group << endl;
    cout << p->key << endl;
    cout << "--------\n";
    p = p->next;
    };
  }


bool CPhoneBook::insertAtEnd(char name[], char phone[], char group[], int key)
  {
  CPhoneEntry *p;
  p = new CPhoneEntry;
  if (NULL == p)
      return false;

  strcpy(p->name, name);
  strcpy(p->phone, phone);
  strcpy(p->group, group);
  p->key = key;
  p->next = NULL;

  if (NULL == first)
      {
      first = p;
      last  = p;
      }
    else
      {
      last->next = p;
      last = p;
      }

  count++;
  return true;
  }


void testInsertAtEnd(void)
  {
    {
    CPhoneBook myBook;
    myBook.display();
    myBook.insertAtEnd("John", "231-7000", "friend", 1);
    myBook.display();
    myBook.insertAtEnd("Tom",  "231-7001", "enemy", 1);
    myBook.display();
    }

    {
    CPhoneBook yourBook;
    yourBook.display();
    }
  }


CPhoneBook::CPhoneBook(void)
  {
  cout << "constructor called\n";
  count = 0;
  first = NULL;
  last = NULL;
  }


void main(void)
  {
  //testInsertAtEnd();
  //testCPhoneBookConstructor();
  //testOperatorOutput();
  testSortByName();
  }