Issues with using a vector

Hello, I am writing a program for a contact manager and I am using istream for inputting data. I need to account for the times in which a user may want to enter multiple phone numbers or emails to their contact. However, when the user enters more than one email, only one shows up. If anyone knows how to fix this, I would greatly appreciate some assistance. Here is my full code. If you have any questions, I will reply ASAP.



[code]
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

class Email {
public:
string emails;
friend class Contact;
vector<int> inputemails; //vector is implemented here
};

class Emails {



};

class Phone {
string number;


};

class Contact : public Phone, public Email { //inheritance for the Email class is here.
//Note that when the vector is removed and it's just a simple string, there are no issues.

///---------------------------------------------------------------------///
string first, last;

string inputE;
int inputEmail;
public:
void userInterface(istream &in,ostream &out,bool search=false) { //i/o streams are implemented here
//code for the names of the contacts
out << "Enter first and last name " << endl;
in >> first >> last;
//-------------------------------------------------

//code for the emails of contacts
out << "Would you like to enter an email? Type yes or no" << endl;
in >> inputE;
if (inputE == "yes") {
out << "How many emails would you like to enter?" << endl;
cin >> inputEmail;
for (int i = 0; i < inputEmail; i++) {
inputemails.push_back(inputEmail);
in >> emails; //This is where my error is.
}

}

}
///--------------------------------------------------------------------///

bool operator ==(const Contact &other) const {
return other.first==first && other.last==last;
}
Contact(string newFirst="",string newLast="", string newEmails="") {
first=newFirst;
last=newLast;
emails = newEmails;
}
string getFirst() {
return first;
}
string getLast() {
return last;
}
string getEmails() {
return emails;
}

friend ostream & operator <<(ostream &out,Contact &other) {
return out << "Name:" << other.first << " " << other.last << " " << "Email:" << other.emails << endl;

}

};

class Contacts {
vector<Contact> people;
public:
void addContact(Contact &newPerson) {
}
void deleteContact(Contact &existingPerson) {
}
vector<Contact>::iterator find(Contact &personName) {
return std::find(people.begin(),people.end(),personName);
}
friend ostream & operator <<(ostream &out,Contacts &other) {
for(unsigned i=0;i<other.people.size();i++)
out << other.people[i];
return out;
}
void userInterface(istream& in, ostream& out);
/*void addPhoneNumber(Contact &existingContact,Phone &newNumber) {
}
void deletePhoneNumber(Contact &existingContact,Phone &existingNumber) {
}*/
};

void Contacts::userInterface(istream &in,ostream &out) {
string cmd;
while (cmd!="exit") {
out << "What do you want to do? "
"You can add, delete, print, or update a contact or exit" << endl;
cin >> cmd;
if (cmd=="print") { out << (*this) << endl; }
else if (cmd=="add") {
Contact c;
c.userInterface(in,out); // Full interface
people.push_back(c);
} else if (cmd=="delete") {
Contact c;
c.userInterface(in,out,true); // Minimum first last name
vector<Contact>::iterator p=find(c);
people.erase(p);
} else if (cmd=="update") {
Contact c;
c.userInterface(in,out,true); // Minimum first last name
vector<Contact>::iterator p=find(c);
p->userInterface(in,out); // Full interface adding/delete
// emails, phones, ....
}
}
}

int main() {
Contacts contacts;
contacts.userInterface(cin,cout);
cout << contacts << endl;
return 0;
};
Last edited on
theres alot of stuff in this thing that isn't exactly wonderful. Like when the thing starts it should basically ask you who you are and bounce you into contact class so that "this" can be called on the current instance. You probably shouldn't be creating a new instance of contact every time a command is given. especially creating an instance so that you can find an existing..... idk.

anyway long story short you weren't actually writing to the vector or printing from it for that matter. Anyways the changes i made aren't exactly the end all be all but it at least saves more than one email and prints out more than one... again not perfect but you should at least be able to see the difference and go from there. I will also add that the print function that i added will/would need a search bc currently it just prints out the inputemails vector that is associated with the last contact instance saved into the contacts.people vector....

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155


#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

class Email {
public:
    string emails;
    friend class Contact;
    vector<string> inputemails; //vector is implemented here
};

class Emails {



};

class Phone {
    string number;


};

class Contact : public Phone, public Email { //inheritance for the Email class is here.
//Note that when the vector is removed and it's just a simple string, there are no issues.

///---------------------------------------------------------------------///
    string first, last;

    string inputE;
    int inputEmail;
public:
    void userInterface(istream& in, ostream& out, bool search = false) { //<~~~~~~~~~~~~~~~ No check of this bool......
    //code for the names of the contacts
        out << "Enter first and last name " << endl;
        in >> first >> last;
        //-------------------------------------------------
        if (search) {
            return;       // <~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~added this
        }
 
        //code for the emails of contacts
        out << "Would you like to enter an email? Type yes or no" << endl;
        in >> inputE;
        if (inputE == "yes") {
            out << "How many emails would you like to enter?" << endl;
            cin >> inputEmail;
            for (int i = 0; i < inputEmail; i++) {
                in >> emails;
                inputemails.push_back(emails);  // <~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~changed this
                
            }

        }

    }
    ///--------------------------------------------------------------------///

    bool operator ==(const Contact& other) const {
        return other.first == first && other.last == last;
    }
    Contact(string newFirst = "", string newLast = "", string newEmails = "") {
        first = newFirst;
        last = newLast;
        emails = newEmails;
    }
    string getFirst() {
        return first;
    }
    string getLast() {
        return last;
    }
    string getEmails() {
        return emails;
    }

    void print() {
        for (int i = 0; i < this->inputemails.size();i++) {  //<~~~~~~~~~~~~~~~~~~added this
            cout << this->inputemails[i] << "\n";
        }
    }

    friend ostream& operator <<(ostream& out, Contact& other) {
        return out << "Name:" << other.first << " " << other.last << " " << "Email:" << other.emails << endl;

    }

};

class Contacts {
    vector<Contact> people;
public:
    void addContact(Contact& newPerson) {
    }

    void deleteContact(Contact& existingPerson) {
    }

    vector<Contact>::iterator find(Contact& personName) {
        return std::find(people.begin(), people.end(), personName);
    }

    friend ostream& operator <<(ostream& out, Contacts& other) {
        for (unsigned i = 0; i < other.people.size(); i++)
            out << other.people[i];
        return out;
    }

    void userInterface(istream& in, ostream& out);
  
};

void Contacts::userInterface(istream& in, ostream& out) {
    string cmd;
    while (cmd != "exit") {
        out << "What do you want to do? "
            "You can add, delete, print, or update a contact or exit" << endl;
        cin >> cmd;
        
        if (cmd == "add") {
            Contact c;
            c.userInterface(in, out); // Full interface
            people.push_back(c);
        }
        else if (cmd == "delete") {
            Contact c;
            c.userInterface(in, out, true); // Minimum first last name
            vector<Contact>::iterator p = find(c);
            people.erase(p);
        }
        else if (cmd == "update") {
            Contact c;
            c.userInterface(in, out, true); // Minimum first last name
            vector<Contact>::iterator p = find(c);
            p->userInterface(in, out); // Full interface adding/delete  <~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~this causes a weird situation update should almost be its own thing
            // emails, phones, ....
        }
        else if (cmd == "print") { 
            this->people.back().print();  //<~~~~~~~~~~~~~~ made changes to this  !! will most likely need a search... and you shouldn't have to add your name it should know who you are...
        }
        
    }
}

int main() {
    Contacts contacts;
    contacts.userInterface(cin, cout);
    cout << contacts << endl;
    return 0;
}
I would think again about your design.
class Contact : public Phone, public Email
Use inheritance for is-a relationship only.
Obviously a phone or email is not a contact.
A contact has email and phone.
I would do it like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Contact
{
public:
  // Constructor
  // getter fuctions
private:
  string first_name;
  string last_name;
  // other fields if needed like nickname, gender, DOB...
  vector<string> emails;
  vector<string>phone_numbers;
};

class ContactCollection
{
public:
  // Constructor
  // load save find add delete methods
private:
  vector<Contact> contacts;
};
Thomas1965:

Thanks for your reply! Unfortunately, this particular task must be programmed in a certain way and I have to write it using phone and email as a separate class. I 100% agree with you though.

markyrocks: Great, that's what I was looking for. Yeah, I gotta clean it up at some point for sure. I greatly appreciate the help, works great! Thank you so much!
[quote name=theforgottenone4]
Thanks for your reply! Unfortunately, this particular task must be programmed in a certain way and I have to write it using phone and email as a separate class. I 100% agree with you though.
[/quote]

Thomas1965 reply is an example of a "HAS A" (composition - is owned by the class) relationship, there is nothing stopping one from doing this inside the class:

1
2
vector<Email> Emails;
vector<Phone> PhoneNumbers;


where Email and Phone are classes or structs.

I agree with Thomas1965, prefer composition or aggregation over inheritance.

https://softwareengineering.stackexchange.com/questions/61376/aggregation-vs-composition

Note the other relation "USES A" (aggregation) normally means in C++ that the type appears as an argument to a class function.

Good Luck !! :+)
Last edited on
Topic archived. No new replies allowed.