Problem with basic I/O.

I'm making a typical beginner's phone/address book program, but I'm having issues with my I/O. At line 26, I've been forced to use std::cout for displaying my contact's name/address/number, because printf won't accept my strings in the form of vector.at(i). The second problem is my user input. When you run the program, and select option 1), it instantly inputs name and skips to number.

If anyone is willing to compile it on their machine, they'll see what I'm talking about. I suspect it might have something to do with my buffer, but I'm not really sure. (Heads up: I call std::system("cls"), which is a Windows only method of clearing the command prompt.)

Anyway, all help (style suggestions or otherwise) will be greatly appreciated.
(Side note: it works just fine when I use std::cin instead of std::getline, but that means the user can't put spaces in the address.)
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
#include <iostream>
#include <vector>
#include <sstream>

class manager{ //Contacts manager class.
    public: //Handles storage, adding contacts, etc.
        manager::manager(std::string targetFile);
        std::vector< std::vector<std::string> >
        contacts;//Vector of string vectors.
        std::string file;
        void viewAll();
        void add(std::string name,
                 std::string  number,
                 std::string address);
        void askAdd();
};
manager::manager(std::string targetFile){
    file = targetFile;//targetFile for persistent storage.
};
void manager::viewAll(){//Displays all contacts.
	std::system("cls");
	int size = contacts.size();
	for (int i=0; i < size; i++){
            std::vector<std::string> contact;
            contact = contacts.at(i);
            std::printf("%s \n", "=========================");
            std::cout << "NAME::" << contact.at(0) << "\n";
            std::cout << "NUMBER::" << contact.at(1) << "\n";
            std::cout << "ADDRESS::" << contact.at(2) << "\n";
            std::printf("%s \n", "=========================");
	}
};
void manager::add(std::string name, //Add contact.
		  std::string number,
	          std::string address){
	std::string oldName;
	int size = contacts.size();
	for (int i; i < size; i++){//Verify the name doesn't
		oldName = contacts.at(i).at(0);//exist.
	    if (oldName == name){
	    	contacts.erase(contacts.begin()+i);
	    	}
    }
	std::vector<std::string> newContact;
	newContact.push_back(name);
	newContact.push_back(number);
	newContact.push_back(address);
	contacts.push_back(newContact);
};
void manager::askAdd(){ //Ask user to add new contact.
	std::string name, number, address;
	std::system("cls");
    std::printf("%s \n","Adding new contact... 99 to end.");

    std::printf("%s \n","Enter NAME: ");
    std::getline(std::cin, name, '\n');
    if (name == "99"){return;}

    std::printf("%s \n","Enter NUMBER: ");
    std::getline(std::cin, number, '\n');
    if (name == "99"){return;}

    std::printf("%s \n","Enter ADDRESS: ");
    std::getline(std::cin, address, '\n');
    if (name == "99"){return;}

    add(name, number, address);
};
// END CLASS manager.........

void dump(){} // pass, do nothing, etc.

void printMenu(){ //Display main menu.
	std::printf("%s \n","<<< Simple Contact Directory >>>");
    std::printf("%s \n","Select an option by number:");
    std::printf("%s \n","1) Add new contact.");
    std::printf("%s \n","2) View all.");
    std::printf("%s \n","3) Search names.");
    std::printf("%s \n","4) Remove contact.");
    std::printf("%s \n","5) Save / Load.");
    std::printf("%s",   "Enter desired menu number... ");
}

int main(){
    std::vector<std::string> contacts;
    bool mainloop = true;
    int choice;
    manager lib("storagefile.txt");
    while (mainloop){
        printMenu();
        std::cin >> choice;
        switch (choice){
			case 1: lib.askAdd();
			case 2: lib.viewAll();
			case 3: dump();
			case 4: dump();
			case 5: dump();
        }
        std::system("cls");
    }

}

Last edited on
closed account (S6k9GNh0)
Suggestion 1: using namespace std;
Suggestion 2: Why use printf in this case?
Suggestion 3:
1
2
3
4
5
6
7
8
9
10
 while (mainloop){
        printMenu();
        std::cin >> choice; //yay for interrupts
        switch (choice){
			case 1: lib.askAdd(); //break;
			case 2: lib.viewAll(); //break;
			case 3: dump();//break;
			case 4: dump();//break;
			case 5: dump(); //Not needed. Just break;
        }


Suggestion 4: //void dump(){} This is a useless and space wasting function.
Suggestion 5: Later, I've got accounting :P
Last edited on
I'm confused; last time I used namespace std I was told it was bad style. Anyway, I used printf because cout won't accept white spaces.
closed account (z05DSL3A)
On line 38, for (int i; i < size; i++){, you have not initialsed i.

You have used std:: alot of places you don't need to, eg printf(), and system().

Putting using namespace std; is not a good solution, it is quick and does save you some typing but you may find you get bitten latter on. There are other ways of reducing your typing

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include...

using std::string;
using std::vector;
...

int somefunc()
{
    using std::cout;
    using std::cin;

    cout << ... // within the scope of this function you 
                     //  can use cout instead of std::cout
}

int main()
{
    string str; // within the scope of the file you can use string 
                    // instead of std::string


}


your switch should be more like:
1
2
3
4
5
6
switch (choice)
{
    case 1: lib.askAdd(); break;
    case 2: lib.viewAll(); break;
    default: break;
}
Last edited on
using std::something? Wow, that's the best C++ advice I've gotten since I started. XD Anyway, all of that clears up a lot. Kudos.
closed account (S6k9GNh0)
Nah, it's not good to use it but there were so many std namespace calls! I thought it was neccessary. Your way is better though T.T.
strings do have a c_string() function which you could use to display it with printf, but cout should show the white spaces. Anyway, the problem with getline is that if anything is in the stream, even a remaining new line, it uses that rather than waiting for user input. You can clear it with cin.sync().
It works! cin.sync() solved the getline problem, and c_string() solves the other issue (actually, that solves several other problems I've been having too.) Many thanks. The new updated code is working fine at the moment, not to mention it looks cleaner without the zillion std::lib calls.

*tip of the hat*

Now to make the other options...
For future reference the function is not called c_string(). It is called c_str()
Hmm, I'm having problems with persistence now. I've tried reading multiple examples, but everything seems a bit tedious. Am I overlooking some useful standard tool? Should I create myself a small persistence toolkit (say, a persistent string vector) or is it time I get a thirdparty library? Any links or small suggestions would be appreciated. At this point though, I don't really know enough to even post code snippets (today is my first day working with C++ persistent storage, actually.)

I plan on doing some hard core googling tonight, but I figure I ought to ask anyway. Forums have a way of answering questions you didn't ask, like the "using std::something" in this thread. Anyway, thanks in advance. =p
What do you mean by "problems with persistance"? Are you talking about not having the variables in scope, or not being able to read the file?
Last edited on
Topic archived. No new replies allowed.