0

I am currently making a phonebook. Once the user has inputted their data, it saves all of the data as a single string (Name, address, phone number, email). I am very new to C++. Any help will be much appreciated. Thanks.

There are two major issues:

  1. After the first contact is saved to the file, the proceeding contacts do not show up in the file

  2. I would like to make it so that the user can search for the name, or one keyword that they inputted as part of their contact, and get the entire string containing ALL of their info. How can I do this?


#include <iostream>
#include <string> 
#include <ostream> 
#include <fstream>   
using namespace std;

struct person{
    string Name;
    string Address;
    string PhoneNumber;
    string Email;
};

int main() {

    ResetUserSelection: 
    int userselection = 0;

    cout << "Press 1 to Add Contact" << endl;
    cout << "Press 2 to Search for Contact"<<endl;
    cout << "What do you want to do? ";
    cin >> userselection;

    if(userselection == 1) {   
        person newPerson;

        cout << endl << "What is your Name? ";   
        cin >> newPerson.Name;

        cout << "What is your Address? " ;
        cin >> newPerson.Address;

        cout << "What is your Phone Number? " ;
        cin >> newPerson.PhoneNumber;     

       cout << "What is your Email? ";
       cin >> newPerson.Email;
       cout << endl;

       cout << newPerson.Name<<"'s contact info"<<endl;
       cout << "Name : " << newPerson.Name <<endl;
       cout << "Address : " << newPerson.Address <<endl;
       cout << "Phone Number : " << newPerson.PhoneNumber <<endl;
       cout << "Email : " << newPerson.Email <<endl;
       cout << endl;

       string fullContact = newPerson.Name + " " + newPerson.Address + " " +       newPerson.PhoneNumber + " " + newPerson.Email; 
       ofstream myfile;
       myfile.open ("contactlist.txt");
       myfile << fullContact;
       myfile.close();
       goto ResetUserSelection;
    } 
    else { 
        string search;
        ifstream Myfile;
        Myfile.open ("contactlist.txt");
        cout << "Who do you want to search for?" << endl;
        cin >> search;

        //i do not know what to do here

        goto ResetUserSelection;
    }
}
JNYRanger
  • 6,829
  • 12
  • 53
  • 81
Billiam
  • 33
  • 5
  • Start by getting rid of the `goto`. If you handed that in as homework to me it would be an instant fail ! – John3136 Apr 21 '15 at 01:33
  • 1
    @John3136 what is wrong with goto? – Billiam Apr 21 '15 at 01:34
  • Maybe you need to search the internet for "stackoverflow c++ read from file structure". – Thomas Matthews Apr 21 '15 at 01:37
  • Type "What is wrong with gotos C++" into google and this is you're top answer: http://stackoverflow.com/questions/3517726/what-is-wrong-with-using-goto – John3136 Apr 21 '15 at 01:41
  • @Billiam `goto` is the best "tool" to create "spaghetti code", which becomes extremely hard to debug. Unless you really need it, just replace it by a loop and a boolean switch. Imagine a large code with 50-60 goto's and you'll see what's the issue. Basically `goto` makes the developer dizzy. – vsoftco Apr 21 '15 at 01:42
  • Ok. Thanks. I'm very confused about saving and searching for strings. I have researched this but am having trouble applying it to my program @vsoftco – Billiam Apr 21 '15 at 01:45
  • @Billiam: I strongly advise you to remove the `goto`. This is what happens if you keep it: https://xkcd.com/292/ – Lee White Apr 21 '15 at 07:07

2 Answers2

0

There are multiple problems with your code:

  1. When you open file you don't append new data to it, you replace it. So everytime there is only 1 record in file. You need to open file in append mode, like this

    myfile.open ("contactlist.txt", ios::app);
    
  2. You don't separate records, probably you would like to add \n when writing contact to file and add something like , to separate its fields.

    string fullContact = newPerson.Name + "," + newPerson.Address + "," + newPerson.PhoneNumber + "," + newPerson.Email + "\n";
    
  3. You can't add contact with whitespaces in name or address. The reason is that you use operator >>. You can replace it with getline function (but you need to add cin.ignore(256, '\n'); after first read operation, see this)

    cin >> userselection;
    cin.ignore(256, '\n');
    
    if(userselection == 1) {
        cout << "What is your Name? ";
        getline(cin, newPerson.Name);
    
        cout << "What is your Address? " ;
        getline(cin, newPerson.Address);
    
        cout << "What is your Phone Number? " ;
        getline(cin, newPerson.PhoneNumber);
    
        cout << "What is your Email? ";
        getline(cin, newPerson.Email);
    
        ....
    }
    
  4. To answer you primary question on how to implement search. One way is to open file, read it line by line, search occurrences of search string in line and if you found it - print

    ifstream myfile;
    myfile.open ("contactlist.txt");
    string contact;
    while(getline(myfile, contact)) {
        if(contact.find(search) != string::npos) {
            cout << contact << endl;
        }
    }
    myfile.close();
    

    you can also replace cin >> search; with getline(cin, search);

Community
  • 1
  • 1
Nikolay K
  • 3,770
  • 3
  • 25
  • 37
0

Not exactly an answer, but some hints for your program.

As you want to write an application managing a phone book you must :

  • identify the informations you want to store (here Name, Address, PhoneNumber, Email) and define the format for each (number vs string, size, allowed characters for a string, case conversion, ...)
  • define a format of storage (text, binary) and make sure in case of a text format that it will not be ambiguous for the format of your informations

Here, you use a space as separator, but you do not seem to forbid a space in a name or address. Second requirement is not met and you will certainly go into trouble. You'd better use as separator a character that is unlikely to happen in your informations like | or ;. Alternatively, you could study how the CSV format deals with escaping special characters.

So beside the problem of opening the file in append mode as said by Nikolai, I strongly advice you to use newline as record separator and | as field separator, and ensure that neither no field can contain those separators.

And as you want to be able to search your phonebook, I also advise you to store names in uppercase (or all lowercase but not a mix) : comparisons will be easier, and if you later use a database, it would be a requirement for correct indexing.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252