Solved

Struct to Class

Posted on 2000-04-05
16
668 Views
Last Modified: 2013-12-14
Hey---

First i want to say this isnt for school or anything that is being graded, it has been graded already, i want this for my own educational purpose.  i made a program that uses struct...it was supposed to been in classes and i never learned it yet.  i am posting the entire code and i appreciate if someone had the time to covnert this program so it utilizes classes.  i really need to learn this topic for the final, but seeing my original and how its supposed to been would help me learn a lot...thank you so much.!~!!!!!!

==============================

/*
   Phone directory program
   Version 1.00
*/

#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

struct phone {
      char name[16];
      char number[5];
}; phone;
   phone directory[50];

void openFile(phone [], int &);
void menu(int &);
void outSave(phone [], int &);
void listName(phone [], int &);
void listNumber(phone [],  int &);
void addEntry(phone[], int &);
void modifyEntry(phone[], int &);
void purgeEntry(phone[], int &);

int main() {
      int k = 0;
    openFile(directory,k);
      menu(k);
      return 0;
}
 
void menu(int &i) {
      
      char menuChoice;
      do {
         cout << "\n\nS)ave to disk\n";
         cout << "A)dd entry\n";
         cout << "D)isplay an entry\n";
         cout << "M)odify an entry\n";
         cout << "P)urge an entry\n";
         cout << "W)ho belongs to an extention\n";
         cout << "Q)uit\n\n>> ";
         cin >> menuChoice;
         menuChoice = char(toupper(menuChoice));
        
         switch (menuChoice) {
            case 'S' :
             outSave(directory,i);
            break;

            case 'A' :
               addEntry(directory,i);
            break;
      
            case 'D' :
               listNumber(directory,i);
            break;

            case 'M' :
               modifyEntry(directory,i);
            break;

            case 'P' :
               purgeEntry(directory, i);
               
            break;
      
            case 'W' :
               listName(directory,i);
            break;
      
            case 'Q' :
                  char ch;
                  do {
                        cout << "\nDo you wish to save before exiting <y/n>: ";
                        cin >> ch;
                        ch = char(toupper(ch));
                        
                        if (ch == 'Y') {
                              outSave(directory,i);
                              cout << "Changed made to file.....Quitting....\n\n";
                              exit(1);
                        }
                        if (ch == 'N') {
                              cout << "Quitting without making any changes....\n\n";
                              exit(1);
                        }

                        else
                              cout << "\nYou must choose yes or no\n";
                  } while (ch != 'Y' || ch != 'N');
            
                  break;

            default :
                cerr << "\nYou made a horrific error and you better try again, bubba\n";
         }
      }while(menuChoice != 'Q');
}

void openFile(phone directory[], int &i) {  
      
      ifstream incoming;
      incoming.open("phone.dat");
    if (!incoming) {
       cerr << "You made a mammouth sized mistake and the computer is now giving up, so there!\n";
       exit(1);
      }


      
      do {
          incoming >> directory[i].name >> directory[i].number;
            i++;
      } while (!incoming.eof());
   
    incoming.close;
      cout << endl << endl;       
}

void outSave(phone directory [], int &i) {

      cout << "\nSaving File\n";
      ofstream outgoing;
    outgoing.open("phone.dat",ios::out);
      int z = 0;
      do {
                  outgoing << directory[z].name << " " << directory[z].number << endl;
                  z++;
        
      } while (z != i+1);

      


      outgoing.close;
      
}

void listName(phone [], int & i) {
    cout << "\nEnter an extention to list a name: ";
    char j[5];
    int r = 0;
    int flag=0;
    cin >> j;
    cout << "\nSearching...\n";
    do {
        if (strcmp(directory[r].number, j) == 0) {
                flag=0;
            cout << endl << directory[r].name << endl;
            break;
            }
   
            else {
                        r++;
                        if (r == i) {
                                    cerr << "Error 320: Not found.\n\n";
                                    menu(i);
                        }
            }
      } while(!flag);
}


void listNumber(phone [], int & i)
{
   cout << "\nEnter name to find extention: ";
   char j[16];
   int r = 0;
   cin >> j;
   cout << "\nSearching...\n";
       
   int fFound = 0;  

   do {
    if ( strcmp ( directory[r].name, j ) == 0 ) {
       cout << endl << r << ". " << directory[r].name << " " << directory[r].number;
       fFound++;  
    }
   r++;
   
   } while ( r < i) ;

    if (!fFound) {
        cerr << "\nError 320: Not found.\n\n";
        menu(i);
    }

return;
}
     
void addEntry(phone[], int &i) {  
      int z = i;
      
      if (z <= 50) {
          cout << "Name: ";
          cin >> directory[z].name;
          cout << "\nNumber for " << directory[z].name << ": ";
          cin >> directory[z].number;
            cout << directory[z].name << " " << directory[z].number << " added." << endl;
      }
      else {
                cerr << "Error 250: Database is full.  Aborting.\n";
                  menu(i);
      }
}

void modifyEntry(phone[], int &i) {
      cout << "\nEnter a name to modify its current number: ";
      char n_Modify[16];
      cin >> n_Modify;
    int r = 0;
      int flag = 0;
      char n_Number[5];
      
      do {
            if (strcmp(directory[r].name, n_Modify) == 0) {
                  flag = 0;
                  cout << "Enter new number for " << n_Modify << ": ";
                  cin >> n_Number;
                  strcpy(directory[r].number,n_Number);
                  break;  
            }

            else {
                        r++;
                        if (r == i)
                              cerr << "Not found.";
            }

      }while (!flag);
}


void purgeEntry(phone[], int &i) {
      cout << "\nEnter a name and it will delete its entire entry: ";
      char d_name[16];
      cin >> d_name;
      int r = 0;
      for( r = 0 ; r < i ; r++ )
            if (strcmp(directory[r].name,d_name) == 0) {
                  directory[r] = directory[i-1] ;
                  i-- ;
                  return ;
            }
      cerr << "Not found.";
}



0
Comment
Question by:weinrj
  • 9
  • 4
  • 3
16 Comments
 
LVL 22

Accepted Solution

by:
nietod earned 1000 total points
ID: 2687664
I woudl change the phone class to use use strings and to have member functions to get and set the name and number, like

class phone {
   string name;
   string number;
public:
   void setName(const string &s)
   {
        name = s;
   };
   string GetName() const
   {
      return name;
   }
   void setNumber(const string &s)
   {
        Number = s;
   };
   string GetNumber() const
   {
      return number;
   }
};
0
 
LVL 22

Expert Comment

by:nietod
ID: 2687676
I would change the  directory array, so it is a class that stores an array of phone nubmers.  I would use a list<> or vector<> to store the phone numbers so that you don't have limited storage, like

class directory
{
   vector<phone> PhnLst;
};
0
 
LVL 22

Expert Comment

by:nietod
ID: 2687690
Then I would add member funcitons to the directory class to perform the various functiosn that it needs to do.  I'm not sure I can figure out all of the ones you need, but I'll get you started.

But first we need to add some constructors to phone, like
class phone {
   string name;
   string number;
public:
   phone() {}; // Default constructor;
   phone (const string &Nam,const string &Num) {
        name(Nam), number(Num) {};
   void setName(const string &s)
   {
      name = s;
   };
   string GetName() const
   {
      return name;
   }
   void setNumber(const string &s)
   {
      Number = s;
   };
   string GetNumber() const
   {
      return number;
   }
};

Then in the directory add

class directory
{
   vector<phone> PhnLst;
public:
   void AddEntry()
   {
       phone NewPhn;
       string Nam;
       string Num;

       cout << "Name: ";
       cin >> Nam;
       cout << "\nNumber for " << Name << ": ";
       cin >> Num;
       PhnLst.push_back(phone(Nam,Num)); // Add to the list.
       cout << Nam << " " << Num << " added." << endl;
   }
};

continues
0
 
LVL 22

Expert Comment

by:nietod
ID: 2687713
this function would also be part fo the directory class (I have to post frequently or I lose my connection, so I posted the direcotry class with out it (and others)).

void listName(i) {
    string Num;
    const int PhnCnt = PhnLst.size();

    cout << "\nEnter an extention to list a name: ";
    cin >> Num;
    cout << "\nSearching...\n";
    for (int i = 0; i < PhnCnt; ++i)    
    {
       if (PhnLst[i].GetNumber == Num)
       {
          cout << endl << PhnLst[i].GetName() << endl;
          return;
       }
    }
    cerr << "Error 320: Not found.\n\n";
}

continues
0
 
LVL 22

Expert Comment

by:nietod
ID: 2687739
it might help  if you had a function that does a search by name.  so I would add the SearchName function that looks for a name and use it to help you write the ModifyEntry function

// return index of entry for specified name.  Return -1 if name not found
int SearchName(const String &Nam)
{
   const int PhnCnt = PhnLst.size();

   for (int i = 0; i < PhnCnt; ++i)    
   {
       if (PhnLst[i].GetName() == Nam)
          return i;
   }
   return -1;
}

then write a modify entry function like

void modifyEntry()
{
   string Nam;
   string Num;

   cout << "\nEnter a name to modify its current number: ";
   cin >> Nam;

   int i = SearchName(Nam);

   if (i == -1)
   {
      cout << Nam <, " was not found" << endl;
      return;
   }
   cout << "Enter new number for " << Nam << ": ";
   cin >> Num;
   PhnLst[i].SetNumber(Num);
};
0
 
LVL 22

Expert Comment

by:nietod
ID: 2687743
The do delete an entry, you would have

void purgeEntry()
{
   string Nam;
   cout << "\nEnter a name and it will delete its entire entry: ";

   cin >> Nam;

   int i = SearchName(Nam);

   if (i == -1)
   {
      cout << Nam << " was not found" << endl;
      return;
   }
   PhnLst.erase(PhnLst.begin() + i) ;
}
0
 
LVL 22

Expert Comment

by:nietod
ID: 2687752
Is that enough to get you started?

try to work with that, if you need more help, why don't you e-mail me the source code at nietod@journey.com.  it gets to be too hard to wrk on long files here on the web.
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 2688447
BTW: a class and a struct are the same .. only difference is that a struct defaults to public members (and basees) and a class to private.

So converting to use classes is merely a matter of changing the word 'struct' ro 'class' and putting in public: infront of anything that yo change from outside the class/struct.

Perhaps what you are really asking for is how to convert from global functions to using member functions.

It would help if the code you had was working first.

You define you functions like this:
 void addEntry(phone[], int &i)
so that means the first parameter (and array of phones) is never used!!! This is WRONG.

Fix your code first.

Then make a struct that is a directory (ie. it has an array of phones as its member).
eg.
struct directory {
  phone m_phones[50];
};

Then change you functions that take phone[] as the first arg so they take a directory instead.

eg.
void addEntry(phone[] mydirectory, int &i);
becomes
void addEntry(directory& mydirectory, int &i);

Then, to make these member functions, you bascially put the declarations inside the directory struct and remove the first arg.

eg.

struct directory {
  phone m_phones[50];
};
void addEntry(directory& mydirectory, int &i);

becomes

struct directory {
  phone m_phones[50];
  void addEntry(int &i);
};
and any 'mydirectory.m_phones' becomes just 'm_phones'

That's about all the needs to be done.  Pretty simple really .. not worth 1000 points, I don't think.

0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 

Author Comment

by:weinrj
ID: 2688462
Well, if someone fixed all my glitches and did the entire coding of everything it would be worth 1000 points...........
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 2688471
If this is truly for your educational purposes, then having someone else do all the work for you isn't going to help.

I (or any other expert) would be very happy to help you through the process.  But just giving you the solution on a silver platter will not help that much with your understanding.

0
 

Author Comment

by:weinrj
ID: 2688476
well this is for education purposes (since that was my lab exam)  i got a 70 on it b/c it wasnt in classes, so i need to learn this....and i dont take silver platters i take Platinum platters instead)
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 2688484
hehehe

Nietod's answer is a very nice platter indeed.
0
 
LVL 22

Expert Comment

by:nietod
ID: 2689314
Did the information I post make sense?  The point was as much HOW to make the changes as much as it was WHAT changes to make.  I.e. so you cou can make the necessary changes int he future.
0
 

Author Comment

by:weinrj
ID: 2690239
your information was very useful, so i need to put like in the int main,

phone blah

so the voids are blah::void stuff()
or somehting right?

also did u leave the fstream a lone?
i didnt check if u did or not.

0
 

Author Comment

by:weinrj
ID: 2690245
because what i did was put the contets of the file phone.dat (standard text file) into the struct....
0
 
LVL 22

Expert Comment

by:nietod
ID: 2690799
I sort of avoided the main() because it was a mess and I was running late.  On closer look it seems your general design is to have a menu function that is called from main, that function then calls a function that cooresponds to the choice made.  At the end of that funcion you just call the menu function again.  This is not good, it leads to extremely high "nesting" of function calls.  Each time a choice is made from a menu you go deeper and deeper.  This can eventualy cause you to run out of spack space an crash.  Even if it doesn't it is a waste of stack space and is totally unnecessary.

A better idea would be to have a loop in main (or iin another function called from main (and only from main()!)    This function would loop until the user choose to quit.  for every choice the user makes the function would call the cooresponding function, just like before, but when that function is donei it would return to this loop and another choice would be made.  

Like


void menu()
{

   char menuChoice;
   while (true) // do until the return in the 'Q' option
   {
       cout << "\n\nS)ave to disk\n";
      cout << "A)dd entry\n";
      cout << "D)isplay an entry\n";
      cout << "M)odify an entry\n";
      cout << "P)urge an entry\n";
      cout << "W)ho belongs to an extention\n";
      cout << "Q)uit\n\n>> ";
      cin >> menuChoice;
     menuChoice = char(toupper(menuChoice));
                         
     switch (menuChoice) {
     case 'S' :
          outSave(directory,i);  // this woudl be a member function
          break;
     *   *   *
      case 'Q' :
      {
          char ch;
          while (true) {
              cout << "\nDo you wish to save before exiting <y/n>: ";
              cin >> ch;
              ch = char(toupper(ch));

              if (ch == 'Y') {
                outSave(directory,i);
                cout << "Changed made to file.....Quitting....\n\n";
                return;
              } else if (ch == 'N') {
                  cout << "Quitting without making any changes....\n\n";
                  return;
              }
              else
                  cout << "\nYou must choose yes or no\n";
               };
     }

If you need more help, i think e-mailing me the source would be best.  It just gets to long and hard to read and fix here.
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Programmer's Notepad is, one of the best free text editing tools available, simply because the developers appear to have second-guessed every weird problem or issue a programmer is likely to run into. One of these problems is selecting and deleti…
Update (December 2011): Since this article was published, the things have changed for good for Android native developers. The Sequoyah Project (http://www.eclipse.org/sequoyah/) automates most of the tasks discussed in this article. You can even fin…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now