Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C++ For Dummies (2004) [eng].pdf
Скачиваний:
84
Добавлен:
16.08.2013
Размер:
8.09 Mб
Скачать

 

 

 

Chapter 24: Using Stream I/O 315

 

 

 

 

 

 

 

 

Table 24-1

Standard Stream I/O Objects

 

 

Object

Class

Purpose

 

 

cin

istream

Standard input

 

 

 

 

 

 

cout

ostream

Standard output

 

 

 

 

 

 

cerr

ostream

Standard error output

 

 

 

 

 

 

clog

ostream

Standard printer output

 

 

 

 

 

The fstream Subclasses

The subclasses ofstream, ifstream, and fstream are defined in the include file fstream.h to perform stream input and output to a disk file. These three classes offer a large number of member functions. A complete list is provided with your compiler documentation, but let me get you started.

Class ofstream, which is used to perform file output, has several construc­ tors, the most useful of which is the following:

ofstream::ofstream(char *pszFileName, int mode = ios::out,

int prot = filebuff::openprot);

The first argument is a pointer to the name of the file to open. The second and third arguments specify how the file will be opened. The legal values for mode are listed in Table 24-2, and those for prot are in Table 24-3. These values are bit fields that are ORed together (the classes ios and filebuff are both parent classes of ostream). (See Chapter 4 for an explanation of the ORing of bit fields.)

The expression ios::out refers to a static data member of the class ios.

Table 24-2

Constants Defined in ios to Control

 

How Files Are Opened

Flag

Meaning

ios::app

Append to the end of the line. Generate an error if

 

the file doesn’t already exist.

ios::ate

Append to the end of the file, if it exists.

 

 

ios::in

Open file for input (implied for istream).

 

 

(continued)

316 Part V: Optional Features

Table 24-2 (continued)

Flag

Meaning

ios::out

Open file for output (implied for ostream).

 

 

ios::trunc

Truncate file if it exists (default).

 

 

ios::noreplace

If file does exist, return error.

 

 

ios::binary

Open file in binary mode (alternative is text mode).

 

 

Table 24-3

Values for prot in the ofstream Constructor

Flag

 

Meaning

filebuf::openprot

Compatibility sharing mode

 

 

 

filebuf::sh_none

 

Exclusive; no sharing

 

 

 

filebuf::sh_read

 

Read sharing allowed

 

 

filebuf::sh_write

Write sharing allowed

 

 

 

For example, the following StreamOutput program opens the file MyName.txt and then writes some important and absolutely true information to that file:

// StreamOutput - simple output to a file #include <fstream>

using namespace std;

int main(int nNumberofArgs, char* pszArgs[])

{

ofstream my(“MyName.txt”);

my << “Stephen Davis is suave and handsome\n”

<<“and definitely not balding prematurely”

<<endl;

system(“PAUSE”); return 0;

}

The constructor ofstream::ofstream(char*) expects only a filename and provides defaults for the other file modes. If the file MyName.txt already exists, it is truncated; otherwise, MyName.txt is created. In addition, the file is opened in compatibility sharing mode.

Referring to Table 24-2, if I wanted to open the file in binary mode and append to the end of the file if the file already exists, I would create the

Chapter 24: Using Stream I/O 317

ostream object as follows. (In binary mode, newlines are not converted to carriage returns and line feeds on output, nor are carriage returns and line feeds converted back to newlines on input.)

void fn()

{

//open the binary file BINFILE for writing; if it //exists, append to end of whatever’s already there

ofstream bfile(“BINFILE”, ios::binary | ios::ate); //...continue on as before...

}

The stream objects maintain state information about the I/O process. The member function bad() returns a TRUE if something “bad” happens. That neb­ ulous term means that the file couldn’t be opened, some internal object was messed up, or things are just generally hosed. A lesser error fail() indicates that either something bad() happened or the last read failed — for example, if you try to read an int and all the program can find is a character that rates a fail() but not a bad(). The member function good() returns TRUE if both bad() and fail() are FALSE. The member function clear() zeros out the error flag to give you another chance. The following program adds basic error checking to the StreamOutput program:

// StreamOutputWithErrorChecking - simple output to a file #include <fstream>

#include <iostream> using namespace std;

int main(int nNumberofArgs, char* pszArgs[])

{

const static char fileName[] = “MyName.txt”; ofstream my(fileName);

if (my.bad()) //if the open didn’t work...

{

cerr << “Error opening file “

<<fileName

<<endl;

return 0;

//...output error and quit

}

my << “Stephen Davis is suave and handsome\n”

<<“and definitely not balding prematurely”

<<endl;

if (my.bad())

{

cerr << “Error writing to file “

<<fileName

<<endl;

}

system(“PAUSE”); return 0;

}

318 Part V: Optional Features

All attempts to output to an ofstream object that has an error have no effect if my.bad() is true.

This last paragraph is meant quite literally — no output is possible as long as the internal error state is non-zero. The program won’t even try until you call clear() to clear the error flags.

The destructor for class ofstream automatically closes the file. In the pre­ ceding example, the file was closed when the function exited.

Class ifstream works much the same way for input, as the following exam­ ple demonstrates:

// StreamInput - simple input from a file using fstream #include <fstream>

#include <iostream> using namespace std;

ifstream* openFile()

{

ifstream* pFileStream = 0; for(;;)

{

// open the file specified by the user char fileName[80];

cout << “Enter the name of a file with integers” << endl;

cin >> fileName;

//open file for reading; don’t create the file //if it isn’t there

pFileStream = new ifstream(fileName); if (pFileStream->good())

{

break;

}

cerr << “Couldn’t open “ << fileName << endl; delete pFileStream;

}

return pFileStream;

}

int main(int nNumberofArgs, char* pszArgs[])

{

// get a file stream

ifstream* pFileStream = openFile();

// stop when no more data in file while (!pFileStream->eof())

{

// read a value int nValue = 0;

Chapter 24: Using Stream I/O 319

(*pFileStream) >> nValue;

//stop if the file read failed (probably because

//we ran upon something that’s not an int or

//because we found a new line with nothing after it) if (pFileStream->fail())

{

break;

}

//output the value just read

cout << nValue << endl;

}

system(“PAUSE”); return 0;

}

The function openFile() prompts the user for the name of a file to open. The function creates an ifstream() object with the specified name. Creating an ifstream object automatically opens the file for input. If the file is opened properly, the function returns a pointer to the ifstream object to use for reading. Otherwise, the program deletes the object and tries again. The only way to get out of the loop is to enter a valid filename or abort the program.

Don’t forget to delete the pFileStream object if the open fails. These are the sneaky ways that memory leaks creep in.

The program reads integer values from the object pointed at by pFileStream until either fail() or the program reaches the End-Of-File as indicated by the member function eof(). An attempt to read an ifstream object that has the error flag set, indicating a previous error, returns immediately without reading anything.

Let me warn you one more time: Not only is nothing returned from reading an input stream that has an error, but also the buffer comes back unchanged. This program can easily come to the false conclusion that it has just read the same value it previously read. Furthermore, eof() will never return a true on an input stream that has an error.

The output from this program appears as follows (I added boldface to my input):

Enter the name of a file with integers chicken

Couldn’t open chicken

Enter the name of a file with integers

integers.txt

1

2

3