I have been working on a contact manager the past couple of days and I decided to construct it using a file. I don't have a ton of experience with input/output with files so I figured this would be a nice opportunity to learn. I know the basics of how to write and read a file but I cannot figure out how to write multiple class instances to one file. I want each class instance to stay in the file and store contact information from user input. The problem I am having is that each time another instance of my class runs through the program, the last instance gets deleted. I want to use a dynamic array so I can't make multiple instances and label them differently.
In short, I need assistance finding a way to have multiple dynamic array instances write to one file without clearing each other.
My full code is below. It's messy at the moment so let me know if you have an issue reading anything. I don't believe you will need to take a look at anything else besides what resides in main. I greatly appreciate any and all help.
void Contact::menu() {
cout << "This is your contact manager. You can add, delete, or view contacts" << endl;
cout << "What would you like to do?" << endl;
cout << "Type A for add" << endl;
cout << "Type D for delete" << endl;
cout << "Type V for view" << endl;
}
void Contact::add(string& Fname, string& Lname, string& email, string& P) { //this is the code for user input
char reply, reply2, reply3;
//user input for contact name
cout << "Enter the first name of the contact " << endl;
cin >> Fname;
cout << "Enter the last name of the contact " << endl;
cin >> Lname;
cout << "Contact's name is " << Fname << " " << Lname << " correct?" << endl;
cout << "Type Y for Yes or type N for No" << endl;
cin >> reply;
if (reply == 'Y' || reply == 'y') {
cout << "\n" << endl;
}
while (reply == 'N' || reply == 'n') {
cout << "Ok, try again" << endl;
cout << "Enter the first name of the contact " << endl;
cin >> Fname;
cout << "Enter the last name of the contact " << endl;
cin >> Lname;
cout << "Contact's name is " << Fname << " " << Lname << " correct?" << endl;
cout << "Type Y for Yes or type N for No" << endl;
cin >> reply;
cout << "\n" << endl;
}
//user input for contact's phone number
cout << "Enter the contact's phone number" << endl;
cout << "Enter the numbers only with no hyphens" << endl;
cin >> P;
cout << "\n" << endl;
cout << "The contact's phone number is " << P << " correct?" << endl;
cin >> reply2;
cout << "\n" << endl;
if (reply2 == 'Y' || reply2 == 'y') {
cout << "Ok, contact's phone number is " << P << endl;
cout << "\n" << endl;
}
while (reply2 == 'N' || reply2 == 'n') {
cout << "Ok, try again" << endl;
cin >> P;
cout << "Contact's phone number is " << P << " correct?" << endl;
cout << "Type Y for Yes or type N for No" << endl;
cin >> reply2;
cout << "\n" << endl;
if (reply2 == 'Y' || reply2 == 'y') {
cout << "Ok, contact's phone number is " << P << endl;
}
}
//user input for contact's email. currently not working fully. type none
cout << "Enter the contacts email or if they have none, type none" << endl;
cin >> email;
cout << "\n" << endl;
if (email == "none" || "None") {
cout << "Your contact does not have an email" << endl;
cout << "\n" << endl;
}
else if (email != "none" || "None") {
cout << "The contact's email is " << email << " correct?" << endl;
cin >> reply3;
cout << "\n" << endl;
if (reply3 == 'Y' || reply3 == 'y') {
cout << "Ok, the contact's email is " << email << endl;
}
while (reply3 == 'N' || reply3 == 'n') {
cout << "Ok, try again" << endl;
cout << "Enter the contact's email " << endl;
cin >> email;
cout << "Contact's email is " << email << " correct?" << endl;
cout << "Type Y for Yes or type N for No" << endl;
cin >> reply3;
cout << "\n" << endl;
if (reply3 == 'Y' || reply3 == 'y') {
cout << "Ok, the contact's email is " << email << endl;;
}
}
}
cout << "Ok! Contact " << Fname << " " << Lname << " has been added to your contact list" << endl;
//Contact Contact1; //Class instances
Contact* newContact = new Contact;
//Contact1.menu();
newContact->menu();
cout << "\nWould you like to do anything with your contact manager?" << endl;
cout << "Type Y for Yes or type N for No" << endl;
cin >> end;
//code to keep contact manager open until user prefers otherwise.
while (end == 'y' || end == 'Y') {
newContact->menu(); //outputs the meny
cin >> menu;
cout << "\n" << endl;
if (menu == 'a' || menu == 'A') { //brings up code for user input
newContact->add(Fname, Lname, email, P);
/**********************************************************************/
//below is the code I have that writes to the file. The file name is list.txt and is, obviously, a text file
ofstream list("text.txt");
if (list.is_open())
{
list << Fname << " " << Lname << endl;
list << "Phone number: " << P << endl;
list << "Email: " << email << endl;
}
else cout << "Unable to open file";
}
/***********************************************************************/
cout << "\n" << endl;
if (menu == 'v' || menu == 'V') {
//the code below outputs the file information. Again, this currently is only outputing one instance of the class
string line;
ifstream myfile("text.txt");
if (myfile.is_open())
{
while (getline(myfile, line))
{
cout << line << '\n';
}
}
else cout << "Unable to open file";
}
cout << "\n" << endl;
cout << "Would you like to do anything else with your contact manager?" << endl;
cout << "Type Y for Yes or type N for No" << endl;
cout << "\n" << endl;
cin >> end;
My first issue is with the code tags and indenting. Have a look at this http://www.cplusplus.com/articles/z13hAqkS/ And remember that just getting the code tags correct does not affect the indenting.
It will take me a bit to load up the code and get it readable to see what is going on.
const std::string outFileName{ "text.txt" };
std::ofstream list(outFileName, std::ios::app);
if (!list)
{
std::cout << "\n File " << std::quoted(outFileName) << " did not open" << std::endl; // <--- Needs header file "iomanip".
// Optional the header file and "std::quoted()".
//std::this_thread::sleep_for(std::chrono::seconds(3)); // <--- Needs header files chrono" and "thread". Optional.
return 1;
}
//ofstream list("text.txt");
//if (list.is_open()) // <--- Always true if the file opened. Not needed with the above if statement.
//{
list << Fname << " " << Lname << endl;
list << "Phone number: " << P << endl;
list << "Email: " << email << endl;
//}
//else cout << "Unable to open file";
}
When it comes to the name of the file stream I like to use "inFile" and "outFile" because they are easier to understand, but you can use any name that you like. Be aware that "list' can be taken in more than 1 way and can be confusing.
I want to use a dynamic array so I can't make multiple instances and label them differently.
You have failed here as you only make 1 instance of the class and not an array. Unless you have to use dynamic memory you would be better off using a vector. You may have to create a vector of pointers to access the dynamic memory.
As it is right now you are not making full use of the class. It just seems to be used for the functions and nothing else. There are better ways to use the class.
Ok, I'm short on time to work on the program at the moment but I read over your comments. This task is meant to showcase dynamic arrays so I am just now learning how to ulitize them. I'll take a look at my textbook for some assistance with the dynamic arrays. Unfortunately, it cannot be a vector.
Instead of the issue with reading and writing to a file, I believe the issue is with the dynamic array. Correct?
Ok, I patched up my code. It seems to be working ok now. Thanks so much for the help! One thing you mentioned is how to fix the dynamic array. Again, I am just now learning about this type of coding so I am very unfamiliar with it, but that will make the array fixed to ten, correct? Is there a way to make the dynamic array that's not fixed to a value?