Simple Phone Book in C++

Today, we will create a simple C++ console application to handle a simple phone book. This phone book will only store people’s name and phone numbers. To obtain this, we have created two classes: Person and PhoneBook. The class Person is described in Person.h like this:
  1. #ifndef PERSON_H
  2. #define PERSON_H
  3.  
  4. #include <string>
  5.  
  6. using namespace std;
  7.  
  8. class Person {
  9. string fullName;
  10. string phoneNumber;
  11. public:
  12. Person();
  13. Person(string, string);
  14. Person(const Person&);
  15.  
  16. string getFullName();
  17. string getPhoneNumber();
  18. bool setFullName(string);
  19. bool setPhoneNumber(string);
  20. };
  21.  
  22. #endif /* PERSON_H */
The implementation of the class Person is very simple, as it has 3 constructors (no parameters, name and phone number as parameters, and copy constructor). Then it has 2 get functions and 2 set functions. The set functions have been made to return false if they fail. Let’s observe the code to set the person’s name:
  1. bool Person::setFullName(string name) {
  2. if (name == "") {
  3. return false;
  4. }
  5. char c = name[0];
  6. if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) {
  7. return false;
  8. }
  9. fullName = name;
  10. return true;
  11. }
The code doesn’t allow an empty name to be set. Further, it doesn’t allow any other beginning character than small or large letters of the English alphabet. The following is the code to set the phone number:
  1. bool Person::setPhoneNumber(string phone) {
  2. if (phone == "") {
  3. return false;
  4. }
  5. int i;
  6. int n = phone.length();
  7. char c;
  8. bool found = false;
  9. for (i = 0; i < n && found == false; i++) {
  10. c = phone.at(i);
  11. if (((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) {
  12. found = true;
  13. }
  14. }
  15. if (found) {
  16. return false;
  17. }
  18. phoneNumber = phone;
  19. return true;
  20. }
As you can see, it won’t allow it if any small or large English letters appear in the phone number, or if the phone number is an empty string. Here is the full code for Person.cpp:
  1. #include <string>
  2. #include "Person.h"
  3.  
  4. using namespace std;
  5.  
  6. Person::Person() {
  7. fullName = "(anonymous)";
  8. phoneNumber = "0";
  9. }
  10.  
  11. Person::Person(string name, string phone) {
  12. fullName = name;
  13. phoneNumber = phone;
  14. }
  15.  
  16. Person::Person(const Person& other) {
  17. fullName = other.fullName;
  18. phoneNumber = other.phoneNumber;
  19. }
  20.  
  21. string Person::getFullName() {
  22. return fullName;
  23. }
  24.  
  25. string Person::getPhoneNumber() {
  26. return phoneNumber;
  27. }
  28.  
  29. bool Person::setFullName(string name) {
  30. if (name == "") {
  31. return false;
  32. }
  33. char c = name[0];
  34. if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) {
  35. return false;
  36. }
  37. fullName = name;
  38. return true;
  39. }
  40.  
  41. bool Person::setPhoneNumber(string phone) {
  42. if (phone == "") {
  43. return false;
  44. }
  45. int i;
  46. int n = phone.length();
  47. char c;
  48. bool found = false;
  49. for (i = 0; i < n && found == false; i++) {
  50. c = phone.at(i);
  51. if (((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) {
  52. found = true;
  53. }
  54. }
  55. if (found) {
  56. return false;
  57. }
  58. phoneNumber = phone;
  59. return true;
  60. }
The PhoneBook class is defined in PhoneBook.h like this:
  1. #ifndef PHONEBOOK_H
  2. #define PHONEBOOK_H
  3.  
  4. #include <string>
  5. #include <list>
  6. #include "Person.h"
  7.  
  8. using namespace std;
  9.  
  10. class PhoneBook {
  11. int nr;
  12. list<Person> people;
  13. public:
  14. PhoneBook();
  15.  
  16. bool addPerson(string, string);
  17. bool addPerson(Person&);
  18.  
  19. list<Person> searchByName(string);
  20. list<Person> searchByPhoneNumber(string);
  21.  
  22. void listAllPeople();
  23. };
  24.  
  25.  
  26. #endif /* PHONEBOOK_H */
We have used C++ list, which is part of the STL. It’s a great way to store custom objects in a linked list. Do note that adding a person will not happen if the name already exists, and when it happens it is automatically added in alphabetical order. This is how adding works:
  1. bool PhoneBook::addPerson(string name, string phone) {
  2. if (nr == 0) {
  3. people.push_back(Person(name, phone));
  4. nr++;
  5. return true;
  6. }
  7.  
  8. bool found = false;
  9. list<Person>::iterator it, itLast;
  10. for (it = people.begin(); it != people.end() && found == false; it++) {
  11. if (((Person) (*it)).getFullName().compare(name) > 0) {
  12. itLast = it;
  13. found = true;
  14. } else if (((Person) (*it)).getFullName().compare(name) == 0) {
  15. return false;
  16. }
  17. }
  18.  
  19. if (found == false) {
  20. people.push_back(Person(name, phone));
  21. nr++;
  22. return true;
  23. }
  24.  
  25. people.insert(itLast, Person(name, phone));
  26. nr++;
  27. return true;
  28. }
If there aren’t Person objects added, we add it and exit. If there are, we make sure we find it’s right place and we also make sure it’s no duplicate. Then, we simply add in the right spot! The search routines are similar: we scan the names/phone numbers, and if the find function doesn’t return npos, it means we have found an entry! If we search “a”, it will return all people whose names include the letter “a”:
  1. list<Person> PhoneBook::searchByName(string name) {
  2. list<Person> l;
  3. if (nr == 0) {
  4. return l;
  5. }
  6. list<Person>::iterator it;
  7. for (it = people.begin(); it != people.end(); it++) {
  8. if (((Person) (*it)).getFullName().find(name) != string::npos) {
  9. l.push_back((Person) (*it));
  10. }
  11. }
  12. return l;
  13. }
  14.  
  15. list<Person> PhoneBook::searchByPhoneNumber(string phone) {
  16. list<Person> l;
  17. if (nr == 0) {
  18. return l;
  19. }
  20. list<Person>::iterator it;
  21. for (it = people.begin(); it != people.end(); it++) {
  22. if (((Person) (*it)).getPhoneNumber().find(phone) != string::npos) {
  23. l.push_back((Person) (*it));
  24. }
  25. }
  26. return l;
  27. }
Here is the simple routine to list all people from the Phone Book:
  1. void PhoneBook::listAllPeople() {
  2. list<Person>::iterator it;
  3. for (it = people.begin(); it != people.end(); it++) {
  4. cout << ((Person) (*it)).getFullName() << " -- " << ((Person) (*it)).getPhoneNumber() << endl;
  5. }
  6. cout << endl;
  7. }
All we did here is to iterate in the list and display name and phone number! Here is the full code for PhoneBook.cpp:
  1. #include <string>
  2. #include <list>
  3. #include <iostream>
  4. #include "Person.h"
  5. #include "PhoneBook.h"
  6.  
  7. using namespace std;
  8.  
  9. PhoneBook::PhoneBook() {
  10. nr = 0;
  11. }
  12.  
  13. bool PhoneBook::addPerson(string name, string phone) {
  14. if (nr == 0) {
  15. people.push_back(Person(name, phone));
  16. nr++;
  17. return true;
  18. }
  19.  
  20. bool found = false;
  21. list<Person>::iterator it, itLast;
  22. for (it = people.begin(); it != people.end() && found == false; it++) {
  23. if (((Person) (*it)).getFullName().compare(name) > 0) {
  24. itLast = it;
  25. found = true;
  26. } else if (((Person) (*it)).getFullName().compare(name) == 0) {
  27. return false;
  28. }
  29. }
  30.  
  31. if (found == false) {
  32. people.push_back(Person(name, phone));
  33. nr++;
  34. return true;
  35. }
  36.  
  37. people.insert(itLast, Person(name, phone));
  38. nr++;
  39. return true;
  40. }
  41.  
  42. bool PhoneBook::addPerson(Person &person) {
  43. return addPerson(person.getFullName(), person.getPhoneNumber());
  44. }
  45.  
  46. list<Person> PhoneBook::searchByName(string name) {
  47. list<Person> l;
  48. if (nr == 0) {
  49. return l;
  50. }
  51. list<Person>::iterator it;
  52. for (it = people.begin(); it != people.end(); it++) {
  53. if (((Person) (*it)).getFullName().find(name) != string::npos) {
  54. l.push_back((Person) (*it));
  55. }
  56. }
  57. return l;
  58. }
  59.  
  60. list<Person> PhoneBook::searchByPhoneNumber(string phone) {
  61. list<Person> l;
  62. if (nr == 0) {
  63. return l;
  64. }
  65. list<Person>::iterator it;
  66. for (it = people.begin(); it != people.end(); it++) {
  67. if (((Person) (*it)).getPhoneNumber().find(phone) != string::npos) {
  68. l.push_back((Person) (*it));
  69. }
  70. }
  71. return l;
  72. }
  73.  
  74. void PhoneBook::listAllPeople() {
  75. list<Person>::iterator it;
  76. for (it = people.begin(); it != people.end(); it++) {
  77. cout << ((Person) (*it)).getFullName() << " -- " << ((Person) (*it)).getPhoneNumber() << endl;
  78. }
  79. cout << endl;
  80. }
Then, lastly, we have created a people.txt file to store some data. In the test program we have read the data and used it to search 2 times and display on screen. Here is the main.cpp file:
  1. #include <iostream>
  2. #include <string>
  3. #include <fstream>
  4. #include <stdlib.h>
  5. #include "Person.h"
  6. #include "PhoneBook.h"
  7.  
  8. using namespace std;
  9.  
  10. PhoneBook *myBook;
  11.  
  12. void readFromFile(string fname) {
  13. int n = 0, i;
  14. string name, phone, nstr;
  15. ifstream fin(fname.c_str());
  16.  
  17. getline(fin, nstr);
  18. n = atoi(nstr.c_str());
  19.  
  20. for (i = 0; i < n; i++) {
  21. getline(fin, name);
  22. getline(fin, phone);
  23.  
  24. myBook->addPerson(name, phone);
  25. }
  26.  
  27. fin.close();
  28. }
  29.  
  30. int main(int argc, char** argv) {
  31. myBook = new PhoneBook();
  32.  
  33. readFromFile("people.txt");
  34.  
  35. list<Person> search;
  36. search = myBook->searchByName("Jo");
  37. cout << "Search by name containing 'Jo'" << endl;
  38. list<Person>::iterator it;
  39. for (it = search.begin(); it != search.end(); it++) {
  40. cout << ((Person) (*it)).getFullName() << " -- " << ((Person) (*it)).getPhoneNumber() << endl;
  41. }
  42.  
  43. cout << endl;
  44. search = myBook->searchByPhoneNumber("23");
  45. cout << "Search by phone number containing '23'" << endl;
  46. for (it = search.begin(); it != search.end(); it++) {
  47. cout << ((Person) (*it)).getFullName() << " -- " << ((Person) (*it)).getPhoneNumber() << endl;
  48. }
  49.  
  50. cout << endl;
  51. cout << "All people in my phone book:" << endl << endl;
  52. myBook->listAllPeople();
  53.  
  54. return 0;
  55. }
Here is how the people.txt file looks like (it has a number N and then N entries, each entry having 1 line for the person’s name and 1 line for the person’s phone number):
  1. 8
  2. John Doe
  3. +123456
  4. Andrew John Luke
  5. +4451551515
  6. Ray George
  7. 1561556165555454
  8. Man Davis
  9. +554545454
  10. Mom
  11. +155151515
  12. Dad
  13. +1515155115
  14. Bro Mark
  15. +15151515
  16. Bro Jack
  17. +1448887
Of course, there are many ways to improve this program! Test and improve as you wish, as possibilities are limitless!

Tags

Add new comment