Home

VCL File Processing: C++ File Streaming

 

Introduction

File processing in C++ is performed using the fstream class. Unlike the FILE structure, fstream is a complete C++ class with constructors, a destructor and overloaded operators.

To perform file processing, you can declare an instance of an fstream object. If you do not yet know the name of the file you want to process, you can use the default constructor.

Unlike the FILE structure, the fstream class provides two distinct classes for file processing. One is used to write to a file and the other is used to read from a file.

Saving a File

Saving a file consists of writing data to disk. To do this, first declare an instance of the ofstream class using one of its constructors from the following syntaxes:

ofstream(const char* FileName, int FileMode);
ofstream();

The ofstream(const char* FileName, int FileMode) constructor provides a complete mechanism for creating a file. It does this with the help of its two arguments. The first argument, FileName, is a string that specifies the name of the file that needs to be saved. The second argument, FileMode, specifies what kind of operation you want to perform on the file. It can be one of the following:

Mode Description
ios::app If FileName is a new file, data is written to it.
If FileName already exists and contains data, then it is opened, the compiler goes to the end of the file and adds the new data to it.
ios::ate If FileName is a new file, data is written to it and subsequently added to the end of the file.
If FileName already exists and contains data, then it is opened and data is written in the current position.
ios::in If FileName is a new file, then it gets created fine as an empty file.If FileName already exists, then it is opened and its content is made available for processing.
ios::out If FileName is a new file, then it gets created fine as an empty file. Once/Since it gets created empty, you can write data to it.
If FileName already exists, then it is opened, its content is destroyed, and the file becomes as new. Therefore you can create new data to write to it. Then, if you save the file, which is the main purpose of this mode, the new content is saved it.*This operation is typically used when you want to save a file.
ios::trunc If FileName already exists, its content is destroyed and the file becomes as new.
ios::nocreate If FileName is a new file, the operation fails because it cannot create a new file.
If FileName already exists, then it is opened and its content is made available for processing.
ios::noreplace If FileName is a new file, then it gets created fine.
If FileName already exists and you try to open it, this operation would fail because it cannot create a file of the same name in the same location.

Image you have a form with three edit boxes whose job is to get the first name, the last name, and the age of a student:

Control Name Caption/Text Other Properties
Bevel      
Label   First Name:  
Edit edtFirstName    
Label   Last Name:  
Edit edtLastName    
Label   Age:  
Edit edtAge    
Bevel      
BitBtn btnOpen Open  
BitBtn btnSave Save  
BitBtn     Kind: bkClose
OpenDialog      
SaveDialog      

You can save its data using a SaveDialog as follows:

//---------------------------------------------------------------------------
#include <vcl.h>
#include <fstream>
using namespace std;
#pragma hdrstop

#include "Exercise.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnSaveClick(TObject *Sender)
{
	char FirstName[30], LastName[30];
	int Age;

	strcpy(FirstName, edtFirstName->Text.c_str());
	strcpy(LastName, edtLastName->Text.c_str());
	Age = edtAge->Text.ToInt();

	if( SaveDialog1->Execute() )
	{
		ofstream Students(SaveDialog1->FileName.c_str(), ios::out);
		Students << FirstName << "\n" << LastName << "\n" << Age;
	}
}

The default constructor, ofstream(), can be used to create an empty stream if you do not yet have enough information about the file you intend to deal with and what type of operation you will perform. This constructor is used if you plan to call member methods to perform the desired file processing.

After declaring an instance of the ofstream class, you can use the ofstream::open() method to create the file. The syntax of the open() method is:

void open(const char* FileName, int FileMode);

This method behaves exactly like, and uses the same arguments as, the constructor we described above. The first argument represents the name of the file you are dealing with and the FileMode argument follows the modes of the above table.

Because the fstream class in this case is declared as ofstream, the compiler is aware that you want to save a file (in reality, the use of ofstream means that you want to write to a file, in other words you want the FileMode with a value of ios::out), you can use the first constructor with just the FileName as argument or you can call the open() method with only the name of the file. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::btnSaveClick(TObject *Sender)
{
	char FirstName[30], LastName[30];
	int Age;

	strcpy(FirstName, edtFirstName->Text.c_str());
	strcpy(LastName, edtLastName->Text.c_str());
	Age = edtAge->Text.ToInt();

	if( SaveDialog1->Execute() )
	{
		ofstream Students;
		Students.open(SaveDialog1->FileName.c_str());
		Students << FirstName << "\n" << LastName << "\n" << Age;
	}
}
//---------------------------------------------------------------------------

After using a file, you should close it. This is taken care by using the ofstream::close() method whose syntax is:

void close(); 
 
 

Opening a File

Besides saving, another operation you can perform consists of opening an already existing file to have access to its contents. To do this, C++ provides the ifstream class. Like ofstream, the ifstream class provides various constructors you can use, two of which are particularly important. If you have enough information about the file you want to open, you can use the following constructor:

ifstream(const char* FileName, int FileMode);

The first argument of the constructor, FileName, is a constant string that represents the file that you want to open. The FileMode argument is a natural number that follows the table of modes as we described above.

If necessary, you can also declare an empty instance of the ifstream class using the default constructor:

ifstream();

After declaring this constructor, you can use the ifstream::open() method to formally open the intended file. The syntax of the open() method is:

open( const char* FileName, int FileMode);

This method uses the same arguments as the above constructor. By default, when declaring an instance of the ifstream class, it is assumed that you want to open a file; that is, you want to use the FileMode attribute with a value of ios::in. Therefore, the second argument is already set to ios::in value. This allows you to call the open() method with just the FileName value.

After using the ifstream class, you can close it using the ifstream::close() method. Here is an example:

//---------------------------------------------------------------------------
#include <vcl.h>
#include <fstream>
using namespace std;
#pragma hdrstop

#include "Exercise.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnSaveClick(TObject *Sender)
{
	char FirstName[30], LastName[30];
	int Age;

	strcpy(FirstName, edtFirstName->Text.c_str());
	strcpy(LastName, edtLastName->Text.c_str());
	Age = edtAge->Text.ToInt();

	if( SaveDialog1->Execute() )
	{
		ofstream Students;
		Students.open(SaveDialog1->FileName.c_str());
		Students << FirstName << "\n" << LastName << "\n" << Age;
	}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnOpenClick(TObject *Sender)
{
	char FirstName[30], LastName[30];
	int Age;

	if( OpenDialog1->Execute() )
	{
		ifstream Students;
		Students.open(OpenDialog1->FileName.c_str());
		Students >> FirstName >> LastName >> Age;
        		Students.close();

		edtFirstName->Text = FirstName;
		edtLastName->Text = LastName;
		edtAge->Text = Age;
	}
}
//---------------------------------------------------------------------------
Home Copyright 2005-2007 FunctionX, Inc.