Okay, so im new to this website/forum. I am in programming 12, and as my final project in C++ I have decided to create an address book application. It will be "simple" and I was hoping to be able to get it to be able to:

1) Create new entry.
2) View all entries.
3) Edit an entry.
4) Delete an entry

I have very minor knowledge in I/O using files, and was hoping to get some help or a tutorial that might help.

Thanks.

Recommended Answers

All 23 Replies

Start by doing the in-memory parts and then you can add serialization to file once it working the way you want. This way you can incrementally add features and also be able to prove to us that you're actually working when you ask for help on the file I/O parts. But a simple google search will give you tutorials and reference material on file I/O as well.

So what you're saying is;

Show us your basic source code and come back when your AT the problem?

What I know so far:

How to "CREATE" a file using i/o in files.
How to "OPEN/Read" a file.

Because what I need to know at the moment is:

How to "CREATE" a file that the user can name. ( I guess I mean an input, example:
" I would like to create a file named 'x' "))

How to "EDIT" a file.

While I probably appear to be another student with a project looking for YOU to make the program for me, I just can't seem to find a tutorial that says how to do these functions.

Thanks :)

>Because what I need to know at the moment is:
>How to "CREATE" a file that the user can name.

std::string filename;

std::cout<<"Enter a filename: ";

if ( getline ( std::cin, filename ) ) {
  // Opening for writing will create the file if it doesn't exist
  // If the file does exist, it will be truncated
  // Note: The constructor requires a C-style string
  std::ofstream out ( filename.c_str() );

  // ...
}

>How to "OPEN/Read" a file.
I'm a strong believer in separate objects for reading and writing. It makes life so much easier when you're not trying to keep up with a read-write stream, so to open a file for reading you would do this:

// Filename from the previous example
std::ifstream in ( filename.c_str() );

// Read from the file like you would std::cin

>How to "EDIT" a file.
Editing a file ultimately ends up as "replacing" the file in practice. Unless you're appending to a file, making changes to random records in a sequential file usually means you have to make all of your changes in memory, then completely overwrite the file (okay for smaller files) or use temporary files to copy and interleave the unchanged segments and your changes, then overwrite the original file with the finished temporary.

Thanks a lot, that helped a ton!

What I meant by "how to edit" was this:

Is it possible to "write" text in c++ and store it in a text file and then to later recall it?

thanks again :)

>Is it possible
The answer is always going to be yes.

>to "write" text in c++ and store it in a text file and then to later recall it?
I'm sorry, didn't I just answer that question with my last post?

> I'm sorry, didn't I just answer that question with my last post?

Im sure you did, I probably just didn't realize it.

So what I have so far is;

Ability to open/read file in c++, ability to create the file in c++.

Sorry for asking the same question over an over, but did you explain to me how to "write" inside of the text file I created? You probably did, im just blind.

>did you explain to me how to "write" inside of the text file I created?
It's just like writing to cout. What more do you need to know?

Okay, perhaps I phrased this wrong, what I am wanting to do is find the code that I need to enable the user (like a cin) to write in that text file.

I know how to write in the file like this,

ofstream myfile ("filename.txt");
  if (myfile.is_open())
  {
    myfile << "This is me writing in the file.\n";
    myfile.close();
  }

But how would I alter the code so that the user can write in the file?

>But how would I alter the code so that the user can write in the file?
Combine the two concepts perhaps? You know, take input from cin, write input to file. :icon_rolleyes:

Okay! After a bit of research and combining the two methods here is what i've come up with so far:

#include <iostream>
#include <string>
#include <fstream>
using namespace std;


int main (){
string name;
string address;
int phone;
string city;
string country;
string line;


// Beging creation of file. 
std::string filename;

std::cout<<"Enter a filename: ";

if ( getline ( std::cin, filename ) ) {
std::ofstream out ( filename.c_str() );
}
// End creation of file.


// Start write to file.
  ofstream myfile ("example.txt");
  if (myfile.is_open())
  {
    cout <<"Please input name: ";
	cin >> name;
    myfile << name;
	    cout <<"Please input address: ";
	cin >> address;
    myfile << address;
	    cout <<"Please input phone number: ";
	cin >> phone;
    myfile << phone;
	    cout <<"Please input city: ";
	cin >> city;
    myfile << city;
	    cout <<"Please input country: ";
	cin >> country;
    myfile << country;
    myfile.close();
  }
// End write to file.


return 0;

}

One problem I am having is figuring out what to put here to make it so that the file I am writing into is the first variable (filename):

// Start write to file.
  ofstream myfile ("example.txt");
  if (myfile.is_open())
  {

Another is that when I open the text file, all of my text is on one line.

Any help?

:)

Okay! After a bit of research and combining the two methods here is what i've come up with so far:

#include <iostream>
#include <string>
#include <fstream>
using namespace std;


int main (){
string name;
string address;
int phone;
string city;
string country;
string line;


// Beging creation of file. 
std::string filename;

std::cout<<"Enter a filename: ";

if ( getline ( std::cin, filename ) ) {
std::ofstream out ( filename.c_str() );
}
// End creation of file.


// Start write to file.
  ofstream myfile ("example.txt");
  if (myfile.is_open())
  {
    cout <<"Please input name: ";
	cin >> name;
    myfile << name;
	    cout <<"Please input address: ";
	cin >> address;
    myfile << address;
	    cout <<"Please input phone number: ";
	cin >> phone;
    myfile << phone;
	    cout <<"Please input city: ";
	cin >> city;
    myfile << city;
	    cout <<"Please input country: ";
	cin >> country;
    myfile << country;
    myfile.close();
  }
// End write to file.


return 0;

}

One problem I am having is figuring out what to put here to make it so that the file I am writing into is the first variable (filename):

// Start write to file.
  ofstream myfile ("example.txt");
  if (myfile.is_open())
  {

Another is that when I open the text file, all of my text is on one line.

Any help?

:)

Writing to the file will be just like using cout. To output a newline using cout, you do this:

cout << "\n";

Do the same with your ofstream:

myfile << "\n";

To open a file whose name is specified in a string variable, you can do this:

std::ofstream out ( filename.c_str() );

which you've already done, except you have a scoping issue and you are outputting your data to myfile, not out.

Delete this line:

ofstream myfile ("example.txt");

and replace this:

if ( getline ( std::cin, filename ) ) {
std::ofstream out ( filename.c_str() );
}

with this:

if ( !getline ( std::cin, filename ) ) {
     std::cout << "Don't have filename.  Exiting.\n";
     exit (1);
}
std::ofstream myfile ( filename.c_str() );

This makes the ofstream that is opened match the ofstream you are writing to and it solves the scoping issue. (you were defining out INSIDE an if statement before, which meant that you can't use it outside outside of that if statement, which is where all of the code using << was.

Thank you, that helped a lot.

I'll post my programs progress in a bit.

Okay, here is the update:

#include <iostream>
#include <string>
#include <fstream>
using namespace std;


int main (){
string name;
string address;
int phone;
string city;
string country;
string line;
int menu;


// Begin Menu
cout << "\nWelcome to the Virtual Address Book!\n" << endl;
cout << "Please select the appropriate option from the menu below...\n" << endl;

cout << "Menu:\n" << endl;

cout << "1 - Create a new contact." << endl;
cout << "2 - View contact information." << endl;
cout << "3 - Edit a contact's information." << endl;
cout << "4 - Delete a contact." << endl;
cout << "5 - Exit program.\n" << endl;
cout << "Please input the corresponding number: ";
cin >> menu;
// End of Menu


// Beging creation of file. 

do {

std::cout<< "Enter a filename: ";
std::string filename;

if ( !getline ( std::cin, filename ) ) {
     std::cout << "Don't have filename.  Exiting.\n";
     exit (1);
}
std::ofstream myfile ( filename.c_str() );
// End creation of file.


// Start write to file.
 if (myfile.is_open())
  {
    cout <<"Please input name: ";
	cin >> name;
    myfile << "Name: " << name << "\n";
	    cout << "Please input address: ";
	cin >> address;
    myfile << "Address: " << address << "\n";
	    cout <<"Please input phone number: ";
	cin >> phone;
    myfile << "Phone Number: " << phone << "\n";
	    cout <<"Please input city: ";
	cin >> city;
    myfile << "City: " << city << "\n" ;
	    cout <<"Please input country: ";
	cin >> country;
    myfile << "Country: " << country << "\n";
    myfile.close();
  }
} while (menu == 1);
// End write to file.


return 0;
}

So now I know pretty much how to add the rest of the functions.

Im running into a problem with the following:

1) The "enter a filename: " is looping, I think it has something to do with my "dowhile loop", i'll probably fix it soon.

2) How would I go about making the program automatically add the ".txt" extension after they enter the filename?

3) To "edit" a contact would I just have to make the program delete the previous file?

Thanks again :)

Okay, here is the update:


So now I know pretty much how to add the rest of the functions.

Im running into a problem with the following:

1) The "enter a filename: " is looping, I think it has something to do with my "dowhile loop", i'll probably fix it soon.

2) How would I go about making the program automatically add the ".txt" extension after they enter the filename?

3) To "edit" a contact would I just have to make the program delete the previous file?

Thanks again :)

1) Not sure if you're looking for help on this one or not since you said you were going to fix it. if you don't want help, skip this next sentence. Anything inside of the do-while loop will repeat. If you want the user to only be prompted one time, you can do the prompting BEFORE the while loop. Is that what you mean? The way you have it now, it will keep asking for a filename.

2) If you want the user to enter "Fred" and have a filename called "Fred.txt" from that, you can simply do this:

filename = filename + ".txt";

3) No need to delete the file. If you have a file that you want to change, simply open the file (if it's already open, close it, then open it again) using an ofstream. Write to that ofstream. Anything that was there before will be overwritten with new information.

#include <iostream>
#include <string>
#include <fstream>
using namespace std;


int main (){
string name;
string address;
int phone;
string city;
string country;
string line;
int menu;
string loop;

	// Begin Menu
	cout << "\nWelcome to the Virtual Address Book!\n" << endl;
	cout << "Please select the appropriate option from the menu below...\n" << endl;

	cout << "Menu:\n" << endl;

	cout << "1 - Create a new contact." << endl;
	cout << "2 - View contact information." << endl;
	cout << "3 - Edit a contact's information." << endl;
	cout << "4 - Delete a contact." << endl;
	cout << "5 - Exit program.\n" << endl;
	cout << "Please input the corresponding number: "; cin >> menu;
	// End of Menu


	// Beging creation of file. 
	std::cout<< "Enter a filename: ";
	std::string filename;
	filename = filename + ".txt";



	if ( !getline ( std::cin, filename ) ) {
	std::cout << "Don't have filename.  Exiting.\n";
	exit (0);
	}
	std::ofstream myfile ( filename.c_str() );
	// End creation of file.

do {
	// Start write to file.
	if (myfile.is_open())
	{
    cout <<"Please input name: ";
	cin >> name;
    myfile << "Name: " << name << "\n";
	    cout << "Please input address: ";
	cin >> address;
    myfile << "Address: " << address << "\n";
	    cout <<"Please input phone number: ";
	cin >> phone;
    myfile << "Phone Number: " << phone << "\n";
	    cout <<"Please input city: ";
	cin >> city;
    myfile << "City: " << city << "\n" ;
	    cout <<"Please input country: ";
	cin >> country;
    myfile << "Country: " << country << "\n";
    myfile.close();
	}
	} while ( menu == 1 );
	// End write to file.


return 0;
}

Excuse the messy code, heh.

I am having complete amnesia right now,

what function should I use for my menu?

because a do/while isn't working, nor does an if statement.

How many files do you want? Just one? I'm getting confused on the whole goal here. If you just want ONE file for all of the contacts, ask for the filename at the top, THEN start your DO-WHILE loop. Put the menu AFTER the DO-WHILE loop starts. Thus you will be prompted for a filename once at the top, then prompted for a menu choice every time, which is what you want, right?

No, I think that I will be doing a file per contact, would that not make it easier to manage/edit?

No, I think that I will be doing a file per contact, would that not make it easier to manage/edit?

Yes, that would make it easier to manage and edit. I would prompt for the person's name and never prompt for the filename. Have the filename be based on the name. Put it inside the loop.

cout << "Name: ";
cin >> name;
std::string filename = name + ".txt";
ofstream myfile (filename.c_str ());

Okay! That really helped.

Here is what I have so far:

#include <iostream>
#include <string>
#include <fstream>
using namespace std;


int main (){
string name;
string address;
int phone;
string city;
string country;
string line;
int menu;
string loop;
string again;


	// Begin Menu
	cout << "\nWelcome to the Virtual Address Book!" << endl;
do {
	cout << "\nPlease select the appropriate option from the menu below...\n" << endl;

	cout << "Menu:\n" << endl;

	cout << "1 - Create a new contact." << endl;
	cout << "2 - View contact information." << endl;
	cout << "3 - Edit a contact's information." << endl;
	cout << "4 - Delete a contact." << endl;
	cout << "5 - Exit program.\n" << endl;
	cout << "Please input the corresponding number: "; cin >> menu;
	// End of Menu



// Option 1 
if (menu == 1) {
cout << "File Name: ";
cin >> name;
std::string filename = name + ".txt";
ofstream myfile (filename.c_str ());

	if (myfile.is_open())
	{
    myfile << "Name: " << name << "\n";
	    cout << "Please input address: ";
	cin >> address;
    myfile << "Address: " << address << "\n";
	    cout <<"Please input phone number: ";
	cin >> phone;
    myfile << "Phone Number: " << phone << "\n";
	    cout <<"Please input city: ";
	cin >> city;
    myfile << "City: " << city << "\n" ;
	    cout <<"Please input country: ";
	cin >> country;
    myfile << "Country: " << country << "\n";
    myfile.close();
	}
} 
// End Option 1

// Option 2
if (menu == 2) {

cout << "\nUNDER CONSTRUCTION 2" << endl;

}
// End Option 2

// Option 3
if (menu == 3) {

cout << "\nUNDER CONSTRUCTION 3" << endl;

}
// End Option 3

// Option 4
if (menu == 4) {

cout << "\nUNDER CONSTRUCTION 4" << endl;

}
// End Option 4

// Option 5
if (menu == 5) {

cout << "\nUNDER CONSTRUCTION 5" << endl;

}
// End Option 5



// Start Menu Prompt
cout << "\nWould you like to go to the main menu? (Yes) or (No): ";
cin >> again;

	} while (again == "yes" || again == "Yes" || again == "YEs" || again == "YES" || again == "yeS" || again == "yES" || again == "YeS");
	
	if (again == "no" || again == "No" || again == "nO" || again == "NO") {
	
	cout << "\nThank you for using the Virtual Address Book, the program will now close." << endl;
	
	}
// End Menu Prompt





return 0;
}

Okay, here is my latest update, I have added the "view contact" code in.

However I am having a slight problem, the program will only "view" the text file if it is "open" and I have not figured out how to "open" the files upon the program loading.

It's hard to explain, if you want you can try and run it and see what I mean.

(You have to create the "new entry" and THEN view it.)

#include <iostream>
#include <string>
#include <fstream>
using namespace std;


int main (){
string name;
string address;
int phone;
string city;
string country;
string line;
int menu;
string loop;
string again;


	// Begin Menu
	cout << "\nWelcome to the Virtual Address Book!" << endl;
do {
	cout << "\nPlease select the appropriate option from the menu below...\n" << endl;

	cout << "Menu:\n" << endl;

	cout << "1 - Create a new contact." << endl;
	cout << "2 - View contact information." << endl;
	cout << "3 - Edit a contact's information." << endl;
	cout << "4 - Delete a contact." << endl;
	cout << "5 - Exit program.\n" << endl;
	cout << "Please input the corresponding number: "; cin >> menu;
	// End of Menu



// Option 1 
if (menu == 1) {
cout << "\nName: ";
cin >> name;
std::string filename = name + ".txt";
ofstream myfile (filename.c_str ());

	if (myfile.is_open())
	{
    myfile << "Name: " << name << "\n";
	    cout << "Please input address: ";
	cin >> address;
    myfile << "Address: " << address << "\n";
	    cout <<"Please input phone number: ";
	cin >> phone;
    myfile << "Phone Number: " << phone << "\n";
	    cout <<"Please input city: ";
	cin >> city;
    myfile << "City: " << city << "\n" ;
	    cout <<"Please input country: ";
	cin >> country;
    myfile << "Country: " << country << "\n";
    myfile.close();
	}
} 
// End Option 1

// Option 2
if (menu == 2) {
std::string filename = name + ".txt";

cout << "Input the name: ";
cin >> name;
 ifstream myfile (filename.c_str ());
  if (myfile.is_open())
  {
    while (! myfile.eof() )
    {
      getline (myfile,line);
      cout << line << endl;
    }
    myfile.close();
  }

  else cout << "Unable to open file"; 

}
// End Option 2

// Option 3
if (menu == 3) {

cout << "\nUNDER CONSTRUCTION 3" << endl;

}
// End Option 3

// Option 4
if (menu == 4) {

cout << "\nUNDER CONSTRUCTION 4" << endl;

}
// End Option 4

// Option 5
if (menu == 5) {

cout << "\nUNDER CONSTRUCTION 5" << endl;

}
// End Option 5



// Start Menu Prompt
cout << "\nWould you like to go to the main menu? (Yes) or (No): ";
cin >> again;

	} while (again == "yes" || again == "Yes" || again == "YEs" || again == "YES" || again == "yeS" || again == "yES" || again == "YeS" || again == "y" || again == "Y");
	
	if (again == "no" || again == "No" || again == "nO" || again == "NO" || again == "n" || again == "N") {
	
	cout << "\nThank you for using the Virtual Address Book, the program will now close." << endl;
	
	}
// End Menu Prompt





return 0;
}

Here is the part of the code that lets the user "view" a contact:

if (menu == 2) {
std::string filename = name + ".txt";

cout << "Input the name: ";
cin >> name;
 ifstream myfile (filename.c_str ());
  if (myfile.is_open())
  {
    while (! myfile.eof() )
    {
      getline (myfile,line);
      cout << line << endl;
    }
    myfile.close();
  }

  else cout << "Unable to open file"; 

}

You have a problem before that too which needs to be solved, as far as creating a new contact. You are using cin and the >> operator, which is fine until you enter more than one word for a name or an address. Then the program doesn't wait for answers on its subsequent questions because it thinks it already has the information. You need to either use getline rather than >> or you need to clear the input stream.

http://www.daniweb.com/forums/thread90228.html

Getline is better for your purposes here.

Regarding the view problem, I'm not 100% sure what you mean. I was able to view my contact (when I only entered single words) with your program.

You said you want to "open the files upon program loading". Keep in mind, you'll have multiple contacts, each with a separate file. You want to open them all at the beginning of the program? Why? And if you only want o open one of them, how do you know which contact the user will want before he/she tells you? Please elaborate.

You have to create the "new entry" and THEN view it.

I'm confused by what you mean here too. How can you view the file before it has been created.

Okay, nevermind I thought the problem was different, here is what happening, you need to "search for a contact" twice, the first time you do it seems to "skip" what you entered, the second time you enter it it works.

HERE IS AN EXAMPLE OF A RUNLOG:


[Session started at 2008-09-30 08:30:23 -0700.]

Welcome to the Virtual Address Book!

Please select the appropriate option from the menu below...

Menu:

1 - Create a new contact.
2 - View contact information.
3 - Edit a contact's information.
4 - Delete a contact.
5 - Exit program.

Please input the corresponding number: 2

Input the name: Test ****** RIGHT HERE IT SKIPS? ******

Would you like to go to the main menu? (Yes) or (No): y

Please select the appropriate option from the menu below...

Menu:

1 - Create a new contact.
2 - View contact information.
3 - Edit a contact's information.
4 - Delete a contact.
5 - Exit program.

Please input the corresponding number: 2

Input the name: Test

Name: Test
Address: Testadd
Phone Number: 123
City: Testcity
Country: Testcou


Would you like to go to the main menu? (Yes) or (No):

The first time I enter the "Name" it just kind of skips it?

What I "think" is happening is the first time I enter the contact name it is "opening" the file for streaming, and the second time I open it, it is opened for reading.

You have a problem here:

if (menu == 2) {
std::string filename = name + ".txt";

cout << "Input the name: ";
cin >> name;
 ifstream myfile (filename.c_str ());
  if (myfile.is_open())
  {
    while (! myfile.eof() )
    {
      getline (myfile,line);
      cout << line << endl;
    }
    myfile.close();
  }

  else cout << "Unable to open file"; 

}

Look at the green and red lines. Are they in the proper order? Let's look what happens. The variable name has some value or is possibly uninitialized, depending on what you have done before with it (i.e. if option 2 is the first option you try when running the program). name is uninitialized or might contain "Test" or it might not. Let's say it's uninitialized, so it has a value of "" . You hit this line:

std::string filename = name + ".txt";

and filename is now ".txt" . THEN you come to this line:

cin >> name;

name now holds "Test" , but filename still holds ".txt" , which is what you attempt to open with this line:

ifstream myfile (filename.c_str ());

so it doesn't work. The NEXT time around, name already holds "Test" from the last time, so it works. So it's not a reading versus writing issue, it's a filename issue. Swap the order the red and green lines and give it a try. Obviously put the cout line above the cin line after you do so.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.