address book using classes

Jan 10, 2022 at 9:35pm
Hi,
the exercise is clear. Create a phone book with the name, last name and phone number. Please have a look on my script. I can't understand the view_friends() is not working :(. How to fix it?

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
#include <iostream>
#include <list>
using namespace std;
void add_friend();
void view_friends();
void print_menu();
void print_info();

    class Friend{
        public:
        string Name;
        string Last_name;
        string phone_number;

        void print_info(){
        cout<<Name<<""<<Last_name<<""<<phone_number<<endl;
        }

        void add_friend(){
        cout<<"Enter name: ";
        cin>>Name;
        cout<<"Enter last name";
        cin>> Last_name;
        cout<<"Enter phone number:";
        cin>>phone_number;
        }
    };

    list <Friend> list_of_friends;

    void print_menu(){
         char ch=0;
         string menu_string= "--- Select ---\n"
                            "1:add\n"
                            "2:View\n"
                            "3: Exit\n";
        do{
           cout<<menu_string;
           if (ch == '1') add_friend();
           else if (ch == '2') view_friends();
       }
       while((ch=cin.get()) !='3');
    }

    void view_friends(){
           for(Friend name: list_of_friends){
           cout<<name<<endl;
       }
    }


int main()
{
    print_menu();
    return 0;
}
Jan 10, 2022 at 10:28pm
try name.print_info() instead of cout << name
your attempt to cout name ... name lacks a friendly << operator or I missed it so you can't stream it. Instead of a convoluted friend stream operator, you can also have your object cast itself to string and then you can print it. you may have to say cout << (string)name if you do that, as those sometimes don't care to be implicit casts, but its another way to defur the feline.

also, range based for loops would do well with a reference:
for( Friend &name: ... ///avoids copy of a fat object every iteration! ideally also make it const.

also, global data is not good design in larger programs, move friends list to main and pass as a parameter and get used to that as a best practice /habit.

examples:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct derp
{
	int x;
	operator string() {return "my value is:"s + to_string(x);}
	 friend ostream& operator<<(ostream& os, const derp& d)
	 { os << d.x; return os; }
};

int main()
{
	derp d;
	d.x = 42;
	cout << (string)d << endl;
	cout << d;
}



my value is:42
42


while the stream operator is nice, I usually want a string.. I almost never output to a console, but I frequently output to a GUI widget... and its minor to use some sort of stringify for both while getting the string out of the stream is annoying (not hard, just cluttery).
Last edited on Jan 10, 2022 at 11:02pm
Jan 11, 2022 at 3:37am
@OP Your data model needs to be thought out more carefully than what you have. There are a numerous basic aspects that could be refined but this 'works':

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
#include <iostream>
#include <list>

using namespace std;

class Friend
{
public:
    string Name;
    string Last_name;
    string phone_number;
    
    void print_info()
    {
        cout << Name << "" << Last_name << "" << phone_number << endl;
    }
    
    void add_friend(){
        cout<<"Enter name: ";
        cin>>Name;
        cout<<"Enter last name";
        cin>> Last_name;
        cout<<"Enter phone number:";
        cin>>phone_number;
    }
};

list <Friend> list_of_friends;

void view_friends();

void print_menu()
{
    Friend temp;
    
    char ch=0;
    string menu_string= "--- Select ---\n"
    "1:add\n"
    "2:View\n"
    "3: Exit\n";
    do{
        cout<<menu_string;
        if (ch == '1')
        {
            temp.add_friend();
            list_of_friends.push_back(temp);
        }
        else if (ch == '2')
        {
            view_friends();
        }
    }
    while((ch=cin.get()) !='3');
}

void view_friends()
{
    for(Friend name:list_of_friends)
    {
        name.print_info();
    }
}

int main()
{
    print_menu();
    return 0;
}


Jan 11, 2022 at 9:42am
Hi! thank you so much for the answers, it works much better but I did not get how to solve the printing menu every interaction. See my update code, I added a pointer & and it's still printing menu after every command:
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
//h
#include <iostream>
#include <list>
using namespace std;
void add_friend();
void view_friends();
void print_menu();
void print_info();

    class Friend{
        public:
        string Name;
        string Last_name;
        string phone_number;

        void print_info(){
        cout<<Name<<" "<<Last_name<<" "<<phone_number<<endl;
        }

        void add_friend(){
        cout<<"Enter name: ";
        cin>>Name;
        cout<<"Enter last name: ";
        cin>> Last_name;
        cout<<"Enter phone number: ";
        cin>>phone_number;
        cout<<" ";
        }
    };

    list <Friend> list_of_friends;

    void print_menu(){

         Friend temp;
         char ch=0;
         string menu_string= "--- Select ---\n"
                            "1:add\n"
                            "2:View\n"
                            "3: Exit\n";
        do{
           cout<<menu_string;
           if (ch == '1'){
            temp.add_friend();
            list_of_friends.push_back(temp);
           }
           else if (ch == '2'){
            view_friends();

           }
       }
       while((ch=cin.get()) !='3');
    }

    void view_friends(){
           for(Friend &name: list_of_friends){
           name.print_info();
       }
    }


int main()
{
    print_menu();
    return 0;
}
Jan 11, 2022 at 10:09am
it's still printing menu after every command:


because of L42. If you don't want that, then move that cout statement.
Topic archived. No new replies allowed.