My C++ Address Book - problems

Started by
8 comments, last by lordoftools 18 years, 8 months ago
Hello, Here is my another project, simple Address Book. I have problems with writing text to a file. I don't know how to write name, surename and phone number, each in new line, and how to read the file line by line? Please download the application and you will see the problem. Please help! Download AddressBook Thank you, RexTroianus
Advertisement
If you're using C++, use the fstream objects to read/write files.

Also, you'd be best off writing the entire struct(With name, etc.) to file(Binary), instead of writing each string itself.

Toolmaker

Quote:Original post by Toolmaker
Also, you'd be best off writing the entire struct(With name, etc.) to file(Binary), instead of writing each string itself.


I wouldn't necessarily recommend that, myself. If you write to the file as separated strings of some sort, it will make debugging WORLDS easier. It may be marginally shorter within the code (four function calls as opposed to two...), and take up marginally less space depending on the implementation, but in modern computing these are definitely not concerns in a case like this.

Just my two cents worth,
Twilight Dragon
{[JohnE, Chief Architect and Senior Programmer, Twilight Dragon Media{[+++{GCC/MinGW}+++{Code::Blocks IDE}+++{wxWidgets Cross-Platform Native UI Framework}+++
Quote:Original post by TDragon
Quote:Original post by Toolmaker
Also, you'd be best off writing the entire struct(With name, etc.) to file(Binary), instead of writing each string itself.


I wouldn't necessarily recommend that, myself. If you write to the file as separated strings of some sort, it will make debugging WORLDS easier. It may be marginally shorter within the code (four function calls as opposed to two...), and take up marginally less space depending on the implementation, but in modern computing these are definitely not concerns in a case like this.

Just my two cents worth,
Twilight Dragon


In addition, if the struct/class you are writing has pointer members, then writing the whole binary blob won't do anything but cause you grief.
Think i solved your problem.

Since you're using chars i avoided strings (which are my preferance) so i used a new variable called chrLine[2000] which corrisponds to each line of your file. It's [2000] because you won't know how big the line will be (subject to change if you wish) but also instead of using >> to input data from the file i used .getline(variable, length) (which is personal preferance im sure it'll work fine if you use >> instead).

As far as the concept changes, i used the function .eof() which returns true if it reaches the end of the file therefore the while loop:

while (!(contact.eof())
{
contact.getline(chrLine,2000);
cout<<chrLine<<endl;
}

will get every line in the file and print it to screen. Also i added endl's (could also use "\n" if you prefer) at the end of each of your lines so that they will be split up into lines instead of in a single line. If you wish to go back to the single line format simply take out the endl's and use then i'd convert the chrLine to a string after the data was extracted and work with std::string::find() with a marker charater in between each bit of data.

Below is the edited .cpp, hope i helped.
(commented everything i added/changed)
[source code=cpp]#include <iostream>#include <fstream>using namespace std;void novi();void open();char name[32], surename[32], tel[32], fname[32];char chrLine[2000]; //for each line of the fileint main(){        system("CLS");    short chc;    cout << "---- Address Book ----\n";    cout << "\n  1. New Contact\n  2. Open Contact\n  3. Exit\n";    cout << "\n Make your choice: ";    cin >> chc;        switch (chc) {           case 1:                novi();                break;           case 2:                open();                break;           case 3:                system("PAUSE");                exit(0);           default:                main();    }        return 0;}void novi(){          system("CLS");     short chc1;     cout << "---- Address Book ----\n";     cout << "\nFirst Name  : ";     cin >> name;     cout << "\nSecond Name : ";     cin >> surename;     cout << "\nPhone Number: ";     cin >> tel;     cout << "\n------------------\n\nSave As: ";     cin >> fname;                    ofstream contact(strcat(fname,".txt"));     contact << "First Name   : " << name << endl; //"<< endl" to split the file into lines of data     contact << "Second Name  : " << surename << endl; //"<< endl" to split the file into lines of data     contact << "Phone Number : " << tel << endl; //"<< endl" to split the file into lines of data     contact.close();           cout << "\n\nContact saved successfuly!\n\n";       system("PAUSE");     main();}void open(){     system("CLS");     short chc1;     cout << "---- Address Book ----\n";     cout << "\nFilename : ";     cin >> fname;          ifstream contact(strcat(fname,".txt"));     if (!contact.is_open()) {            cout << "\nCould not find the file!\n\n";                                                                }          else {          cout << "\n------------------\n\n";          //you had contact >> name; cout << name;          while (!(contact.eof()) //will loop til end of file (including last line)	  {		contact.getline(chrLine,2000); //stores the line up to 2000 chars into chrLine		cout<<chrLine<<endl; //prints chrLine	  }          cout << "------------------\n\n";                     }                    system("PAUSE");     main();}
-Lordoftools"Knowledge is not only a gift it's a responcibility."
Also i can see by the code that you prolly don't want to make this a huge project but i'd buffer for your char arrays maybe being too big (ie. a 33 char name, which surprisingly can happen with certain countries and how they add last names together during marrage and such) and i'd also give a list of the currently saved contacts or even better save all the contacts in 1 file and pull them out that way.

Again those are only suggestions but if you wish to do any of that i can help you out, i just finished a 2600 line project which revolves around file manipulation (kinda proud of myself and seeking to pass on my new knowledge).

-Lordoftools
-Lordoftools"Knowledge is not only a gift it's a responcibility."
Another solution would be to use XML, which is very readable and usually easy to handle.

I used TinyXML in 2 projects, and I loved it.

Toolmaker

Guys, thank you so much for replies!

lordoftools, I used your code, and works perfect! Thank you very much. Can you help me and tell me how to save all contacts in one file?

Rex
hey dude here's my email lordoftools@hotmail.com, drop me a line and we can talk there, i'd love to help you out with anything that i can.

-Lordoftools
"Knowledge is not only a gift it's a responcibility."
-Lordoftools"Knowledge is not only a gift it's a responcibility."
alright i caught writters block on a program i was writing so i did your program for you out of boredum since you never contacted me for the help you claimed to want.

features i added above and beyond yours:
-put all contacts into one file "contacts.txt"
-enabled browsing of the contact names
-put in error traping incase of issues with the file
-seperated the information by line so that you can extract it easily

issues:
as of now there is a bug that i havn't worked on yet. after you edit a contact if you go back to the main menu and immidiatly try to open it, it will give you wrong information. But if you then go back to the menu and try to open it again everything will be fine and will always be fine after that. It's a minor glitch and all the proper information is accurate in the file and will display accuratly in every other case besides opening it immediatly after editing that specific contact.

the bright side:
if you fix this bug you can assume that you have now mastered the code which i've put in there for you. so i'd advise hunting down this bug if only to learn how i added the features i put in.

here's the code:
[source code=cpp]#include "stdafx.h"#include <iostream>#include <fstream>//helps with string convertions#include <sstream>//for getch()#include <conio.h>using namespace std;void novi();void open();void SaveContact();bool CheckSaved();void ContactMenu();char name[32], surename[32], tel[32], fname[32];char chrLine[2000]; int i;int main(){    	string strTemp;    system("CLS");    short chc;    cout << "---- Address Book ----\n";    cout << "\n  1. New/Edit Contact\n  2. Open Contact\n  3. Browse Contacts\n  4. Exit\n";    cout << "\n Make your choice: ";    cin >> chc;        switch (chc) 	{           case 1:                novi();                break;           case 2:                open();                break;		   case 3:			    ContactMenu();				break;           case 4:                system("PAUSE");                exit(0);           default:                main();    }        return 0;}void novi(){          system("CLS");     cout << "---- Address Book ----\n";     cout << "\nFirst Name  : ";     cin >> name;     cout << "\nSecond Name : ";     cin >> surename;     cout << "\nPhone Number: ";     cin >> tel;     cout << "\n------------------\n\nSave As: ";     cin >> fname;               	 SaveContact();          cout << "\n\nContact saved successfuly!\n\n";       system("PAUSE");     main();}void open(){	string strTemp;     system("CLS");     cout << "---- Address Book ----\n";     cout << "\nContact Name : ";     cin >> fname;          fstream inFile("contacts.txt", ios::in);     if (!inFile.is_open()) {            cout << "\nCould not find the file!\n\n";                                                                }          else 	 {		cout << "\n------------------\n\n";		inFile.getline(chrLine,2000);		//convert to string array		strTemp=chrLine[0];		for (i=1; i<=1999; i++)			strTemp=strTemp+chrLine;				while ((!(inFile.eof())) && strTemp.find(fname)==std::string::npos)		{			inFile.getline(chrLine,2000);			//convert to string array			strTemp=chrLine[0];			for (i=1; i<=1999; i++)				strTemp=strTemp+chrLine;		}		//disp the info		while((!(inFile.eof())) && strTemp.find("[END CONTACT]")==std::string::npos)		{			inFile.getline(chrLine,2000);			//convert to string array			strTemp=chrLine[0];			for (i=1; i<=1999; i++)				strTemp=strTemp+chrLine;			if (strTemp.find("[END CONTACT]")==std::string::npos)				cout<<strTemp<<endl;					}        cout << "\n------------------\n\n";                     }          	 cout<<"Press any key to return to the Main Menu ...";     getch();     main();}//checks to see if the contact already exists or notbool CheckSaved(){	string Data="contacts.txt", strTemp;	ifstream inFile(Data.c_str());	//check for file existance	if(!(inFile.good()))	{		inFile.close();		//Create file		ofstream outFile(Data.c_str());		outFile.close();	}	//checks for contact existance	while (inFile.getline(chrLine,2000))	{		//convert to string		Data=chrLine[0];		for(i=1;i<=1999;i++)			Data=Data+chrLine;		//find contact		if (Data.find(fname) !=std::string::npos)		{			inFile.close();			return(true);		}	};		//close file for neatness	inFile.close();	return (false);}//rewrites the files needed for savingvoid SaveContact(){	bool Saved;	string Data="contacts.txt", strOldData[100], strOldData2[100], strTemp;	char chrLine[2000];	int cnt=0;	//empty strOldData incase this isn't the first save	for (i=0; i<=99; i++)		strOldData=" ";	//empty strOldData2 incase this isn't the first save	for (i=0; i<=99; i++)		strOldData2=" ";	//check to see if the contact is overwritting or a new save	Saved=CheckSaved();	if (Saved==false)	{		fstream outFile(Data.c_str(), ios::out|ios::app);				//write the new info				outFile<<endl<<endl;		outFile << "[START CONTACT = " << fname <<"]"<<endl;		outFile << "First Name   : " << name << endl; 		outFile << "Second Name  : " << surename << endl; 		outFile << "Phone Number : " << tel << endl; 		outFile << "[END CONTACT]" <<endl;		outFile.close();	}	else	{		//open file		fstream inFile(Data.c_str(), ios::in);		//store information in file before the saved game for reprint		cnt=0;		inFile.getline(chrLine,2000);		//convert to string array		strOldData[cnt]=chrLine[0];		for (i=1; i<=1999; i++)			strOldData[cnt]=strOldData[cnt]+chrLine;		//load pre-contact data		while (strOldData[cnt].find(fname)==std::string::npos)		{			cnt++;						inFile.getline(chrLine,2000);			//convert to string array			strOldData[cnt]=chrLine[0];			for (i=1; i<=1999; i++)				strOldData[cnt]=strOldData[cnt]+chrLine;		};		//remove the contact from the pre-contact game data		strOldData[cnt-1]=" ";		strOldData[cnt]=" ";		//if the contact was found on the first getline clear it out		if (strOldData[1]==" ")			strOldData[0]=" ";		//store information in file after the saved contact for reprint		inFile.getline(chrLine,2000);		//convert to string array		strTemp=chrLine[0];		for (i=1; i<=1999; i++)			strTemp=strTemp+chrLine;		//scan until it finds the line with the end marker		while (strTemp.find("[END CONTACT]")==std::string::npos)		{			inFile.getline(chrLine,2000);						//convert to string array			strTemp=chrLine[0];			for (i=1; i<=1999; i++)				strTemp=strTemp+chrLine;		};		//store the rest of the file		cnt=0;		while (!(inFile.eof()))		{			inFile.getline(chrLine,2000);			//convert to string array			strOldData2[cnt]=chrLine[0];			for (i=1; i<=1999; i++)				strOldData2[cnt]=strOldData2[cnt]+chrLine;			cnt++;		};		//if the contact was found on the first getline clear it out		if (strOldData2[1]==" ")			strOldData2[0]=" ";		inFile.close();				//rewrite the begining old info [1]		cnt=1;		fstream outFile(Data.c_str(), ios::out);		if (!(strOldData[0]==" "))			outFile<<strOldData[0];		while (!(strOldData[cnt]==" "))		{			outFile<<endl<<strOldData[cnt];			cnt++;		};		//write the new info			outFile<<endl<<endl;		outFile << "[START CONTACT = " << fname <<"]"<<endl;		outFile << "First Name   : " << name << endl;		outFile << "Second Name  : " << surename << endl;		outFile << "Phone Number : " << tel << endl;		outFile << "[END CONTACT]" <<endl;		//rewrite the end old info [2]		cnt=1;		if (!(strOldData2[0]==" "))			outFile<<strOldData2[0];		while (!(strOldData2[cnt]==" "))		{			outFile<<endl<<strOldData2[cnt];			cnt++;		};		outFile.close();	}	main();}//Displays the contacts availablevoid ContactMenu(){	//Function level Declarations	string Contact[100], Data="contacts.txt", strTemp;	int cnt=0, intTemp;	char chrLine[2000];	//initialize the Contact array	for (i=0; i<=99; i++)		Contact=" ";	//storing the Contacts into an array to be printed	ifstream inFile(Data.c_str());	system("cls");	//check for file existence	if(!(inFile.good()))	{		//Print menu		cout<<"File 'contacts.txt' was not found no saved Contacts are available.\n\n";		cout<<"Press any key to return to the Main Menu.";		getch();		inFile.close();		//return to main menu		system("cls");		main();	}	while (!(inFile.eof()))	{		inFile.getline(chrLine,2000);		strTemp=chrLine;		//look for the name locator		if(!(strTemp.find("[START CONTACT = ")==std::string::npos))		{			intTemp=strTemp.find("[START CONTACT = ")+17;			//remake the string with chrLine			strTemp=chrLine[intTemp];			intTemp++;			while (strTemp.find("]")==std::string::npos)			{				strTemp=strTemp+chrLine[intTemp];				intTemp++;				if(intTemp==2000)					strTemp=strTemp+"]";			}			strTemp=strTemp.substr(0,strlen(strTemp.c_str())-1);			Contact[cnt]=strTemp;			cnt++;		}	};	//check for which menu to use	if (!(Contact[0]==" "))	{		//Print menu		cnt=0;		system("cls");		cout << "---- Address Book ----\n\n";		while (!(Contact[cnt]==" "))		{			cout<<cnt+1<<". "<<Contact[cnt]<<".\n";			cnt++;		}		cout << "\n------------------\n\n"; 		cout<<"Press any key to return to the Main Menu ...";				getch();	}	else	{		//if there's no saved Contacts print this menu		system("cls");		cout<<"Sorry no saved Contacts were found.\n\n";		cout<<"Press any key to go back to the Main Menu.";		getch();		main();	}	main();}


-Lordoftools
"Knowledge is not only a gift, it's a responsibilty."
-Lordoftools"Knowledge is not only a gift it's a responcibility."

This topic is closed to new replies.

Advertisement