Contents  1-5  6-11  12-16  17-21  22-27   28-33  34 - 38  39-46  Projects   MFC

   Contact
   Search
   C
   C++
   Visual Basic
   Java
   JavaScript
   DHTML
   Style Sheets
   About
   Active X
   TDC Binding
   PHP
   Perl and CGI
   Flash
   XML
   SQL
   Messages
   Chat
   MCSE
   Linux
   Cabling   
   ActionScript
   Downloads
   E-Cards   
 
    
    

Well, now that we've got the basics of C++ down, wouldn't it be nice if we could save all this data we've been
meticulousy preparing?  File access is where we can begin to expand our horizons into all sorts of new directions.  This
is where we can lay the foundation for databases, applications and games.  This is where the rubber meets the road,
so to speak.

To create, manipulate, write to and read from files in C++, we need the fstream class.  You will need to
#include <fstream.h> in your source file to enable this class's methods and functions.  To read and write files, you will need to create instances of:

ifstream - for reading from files and input.             Syntax for creating an instance:  ifstream InputFile;
ofstream - for writing to files and output.               Syntax for creating an instance: 
ofstream OutputFile;

Once you instantiate objects from ifstream and ofstream, you may use the open and close methods on your objects via the dot operator:

open() - opens a file.      Syntax:   OutputFile.Open("TheFileName",ios::METHODS);
close() - closes a file.     Syntax:   
OutputFile.close();   

There are several modes you need to pass in to the open() method when you use it:

ios::in - Opens the file for input.  This is the default for ifstream objects.
ios::out - Opens the file for output.  This is the default for ofstream objects.
ios::app - Opens file for append, allows writing new data to the end of an existing file.  If  no file, the file will be created.
ios::binary - Opens/creates a binary file.  With binary files, entire objects can be written and read at once via pointers.
ios::ate - Seek to end of file when open ( "ate" = at end).
ios::nocreate - If the file does not exist, do not create a new file.
ios::noreplace - If the file already exists, do not overwrite it.
ios::trunc - Open and truncate an existing file.  New info written to the file will replace its contents.

 Let's look at a syntax example:

ifstream InputFile;
ofstream OutputFile;
InputFile.open("data.txt",ios::in);
OutputFile.open("data.txt", ios::out);
OutputFile.close();

There are some useful methods that go with ifstream and ofstream objects:

is_open - If file opens successfully, a boolean "true" is returned.  If not, false is returned.      Syntax:  Object.is_open();
eof() - Returns the boolean value "true" if at the end of a file, otherwise it returns false.       Syntax: 
Object.eof();
ignore() - ignores specified number of chars.  Cleans input stream/searches.        Syntax: Object.ignore(N, deLimiter);
get() - Gets line.  Takes 3 parameters: 1) string/char array, 2) max chars to get, 3) delimiter char to terminate input. 
           Syntax: 
Object.get(StringOrCharArray, MAXchars, deLimiterChar);

To prevent data loss, be sure you always close any files that are open before a program ends.  Now that we can open and close files, how do we write data to them?   Hint: You have been using this tool since lesson 1 and your "Hello World" application.  In C++, we can send data to and retrieve data from a file via the datastream operator and cin/cout, just as we would from the keyboard and to the console.  Example:

#include <iostream.h>
#include <fstream.h>
void main() {
     ofstream OutputFile; 
//Step 1
     OutputFile.open("income.txt",ios::out); 
//Step 2
     int Income = 0;
     cout << "Enter weekly income.  (Enter -1 to stop.)";
     cin >> Income;
     while(Income != -1)
     {
           OutputFile << Income << endl; 
//Step 3
           cout <<  "Enter weekly income.  (Enter -1 to stop.)";
           cin >> Income;
     }
     OutputFile.close(); 
//Step 4
}
//close main()  

Notice there are always 4 basic processes to writing: 

  • Create the instance

  • Open the file

  • Write to it (stream the data)

  • Close the file.

Here's an example of writing strings to a file:

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

void main() {
     ofstream OutputFile;
     OutputFile.open("GoodMovie.txt",ios::app);
    
     string GiantLizard = "Godzilla ";
     string ModernCity = " Tokyo";
     string Action = "";
    
     cout << "Give me an action verb: ";
     cin >> Action;
    
     OutputFile << GiantLizard << Action << ModernCity << "." << endl;
    
     OutputFile.close();
}

Output to a file using strings, c_str() and appending a file extension - ".txt":

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

void main() {

     string FileName = "";
     string Extension = ".txt";
     cout << "Enter a name for the file: ";
     cin >> FileName;
    
     FileName = FileName + Extension;

    
//Here, we have to convert the sting into a char pointer in order to pass it to open()
     const char * TheFile = FileName.c_str();

     ofstream OutputFile;
     OutputFile.open(TheFile, ios::app);
    
     string GiantLizard = "Godzilla ";
     string ModernCity = " Tokyo";
     string Action = "";
    
     cout << "Give me an action verb: ";
     cin >> Action;
    
     OutputFile << GiantLizard << Action << ModernCity << "." << endl;
    
     OutputFile.close();
}

In the example above, we used the overloaded + operator of the string class to concatenate what the user types in with the file's extension, ".txt".  We had to use the c_str() method to convert the string object "FileName" to a char pointer, because we can not feed a string into the first argument for open() directly.  We can, however, feed a pointer to a char.  

We could have forgone the strings and used used plain old char arrays for the filename, but we would have had to cycle through the elements one by one via a loop in order to add the file extension to the end of the char array.   How's that, you say?   Just check for an ASCII value, then append the text char by char, element by element.  It's what the string class is doing for us all the time anyway, behind the scenes.   Yes, we can do what we are about to do below, but the string/c_str way is a lot smoother.  Let's do it anyway -  I'm a twisted soul.  :)  We could also use strcpy() and strncpy() to copy one char array to the other, but this time, for once,  we're going to reinvent the wheel so that we can see what goes on behind the scenes when copying arrays.   Example:

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void main() {
         char TheFile[20] = "";
	 char FileName[10] = "";
	 char Detect;
     cout << "Enter a name for the file followed by a (*): ";
     cin >> FileName;

     cin.ignore(1);
     for(int x = 0; x<=10 ; x++)
		  TheFile[x] = FileName[x];
	 
     for(int z = 0; z<=20 ; z++) 
	 {
	     Detect = TheFile[z];
		 if(Detect == '*')
		 {	
			 TheFile[z] =    '.';
			 TheFile[z+1] =  't';
                         TheFile[z+2] =  'x';
			 TheFile[z+3] =  't';
			 z = 100;  //Or break; - whatever ...
		 }
	 }
	  	 
     ofstream OutputFile;
     OutputFile.open(TheFile, ios::app);
     string GiantLizard = "Godzilla ";
     string ModernCity = " Tokyo";
     string Action = "";
     cout << "Give me an action verb: ";
     cin >> Action;
     OutputFile << GiantLizard << Action << ModernCity << "." << endl;
     OutputFile.close();
}

Let's expound on ignore.  Remember, ignore() ignores a specified number of characters.  It is useful for cleaning out the input stream of terminating Nulls and line returns, and for searching/parsing data in the input stream.  When using the getline() function, you will need to use ignore() a lot to keep your code from being buggy.  You will recall that several examples ago we used getline() in a letter guessing game.  This code was buggy without the appropriate use of ignore.  This is because getline() waits until the user hits return before passing the input data to the stream.  It then removes the line return "\n", and leaves it in the stream.  This can cause getline() to skip lines of input, assigning the wrong value to variables, or not even asking the user for input at all.  The ignore() function can be used to clean out the stream and remedy this situation.  It takes two arguments: 1 - the number of chars to ignore, and 2 - the deLimiter character.  The ignore() function will ignore to the specified number of chars or until it reaches what you specify as the delimiter.  If it reaches the delimiter first, it will stop.

Let's look at opening a file and reading data from it.  Examples:

Input from a file using the stream operator, a loop and strings:

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

void main() {
     ifstream InputFile;
     InputFile.open("GoodMovie.txt",ios::in);

     string FileContents1 = "";
     string FileContents2 = "";

     while(!InputFile.eof())
     {
          InputFile >> FileContents1;
          FileContents2 = FileContents2 + " " + FileContents1;
     } 

     cout << FileContents2 << endl << endl;

     InputFile.close();
}

Input from a file using getline() and strings:

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

int main() {
     ifstream InputFile;
     InputFile.open("SalesData.txt",ios::in);

     if(InputFile.is_open())
     {
        string SalesPerson = "";
        int sales = 0;
       
        getline(InputFile, SalesPerson, '#');

        while(!InputFile.eof())
        {
            InputFile >> sales;
            InputFile.ignore(1);
      
            cout << SalesPerson << ": " << sales << endl;
            getline(InputFile, SalesPerson, '#');
        }
//close while true
       
        InputFile.close();

     }
//close if

     
     else {
            cout << "Sorry, could not open file." << endl;
          }

     return 0;
}

Contents of the file "SalesData.txt":

Charles Germany # 12000
Drew Berrymore # 24000
George W. Bush # 200000
Bill Gates #1000000
Output:
Charles Germany : 12000
Drew Berrymore : 24000
George W. Bush : 200000
Bill Gates : 1000000

Input from a file using a while(true) loop, the stream operator and char arrays:

#include <fstream>
#include <iostream>
using namespace std;
int main()
{
	char FileName[80];
	char buffer[255];    
	cout << "File name: ";
	cin >> FileName;
	ofstream OutputFile(FileName);  
	OutputFile << "This line written directly to file...\n";
	cout << "Enter text for the file: ";

	cin.ignore(1,'\n');    //Consume the newline "\n" after the file name

	cin.getline(buffer,255);   
	OutputFile << buffer << "\n";   
	OutputFile.close();            
	ifstream InputFile(FileName);
	cout << "Here's the contents of the file:\n";
	char ch;

	while(InputFile.get(ch))   //get(ch) will fetch the chars in the file one by one till the end
        {	      
            cout << ch;            //chars displayed one by one
        }
	cout << "\n\nThat\'s the whole file.\n\n";
	InputFile.close();
            
	return 0;
}

Input from a file using the getline() function and char arrays:

#include <fstream>
#include <iostream>
using namespace std;
int main()   //Return -1 on error
{
	char FileName[80];
	char buffer[255];
	cout << "Please re-enter the file name: ";
	cin >> FileName;
	ifstream InputFile(FileName);
	if(InputFile)                         //Does the file exist?
	{
		cout << "Current file contents:\n";
		char ch;

		while(InputFile.get(ch)) 
                {		  
                      cout << ch;  //Get each char in the file one by one
                }

		cout << "\n***End of file contents.***\n";
	}

	InputFile.close();
	cout << "\nOpening " << FileName << " in append mode...\n";
	ofstream OutputFile(FileName,ios::app);
	if (!OutputFile)
	{
		cout << "Unable to open " << FileName << " for appending.\n";
		return(-1);   //Return -1 on error
	}
	cout << "\nEnter text for the file: ";

	cin.ignore(1,'\n');
	cin.getline(buffer,255);

	OutputFile << buffer << "\n";
	OutputFile.close();
	InputFile.open(FileName);  

	if(!InputFile)
	{
		cout << "Unable to open " << FileName << " for reading.\n";
		return(1);
	}

	cout << "\nHere's the contents of the file:\n";

	char ch;

	while(InputFile.get(ch))
        {
		cout << ch;
        }
	cout << "\n***End of file contents.***\n";

	InputFile.close();

	return 0;
}

 



©2004 C. Germany