|

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:
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
|