1. Trang chủ
  2. » Công Nghệ Thông Tin

Absolute C++ (4th Edition) part 50 pdf

10 1K 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 265,04 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

12 Streams and File I/O12.1 I/O STREAMS 501 File I/O 501 Pitfall: Restrictions on Stream Variables 506 Appending to a File 506 Tip: Another Syntax for Opening a File 508 Tip: Check That

Trang 1

Programming Projects 497

10 The program would behave exactly the same However, most authorities favor using the using declaration, as we have done in Display 11.10 Note that with either, there are still two different functions named readHour The one in Display 11.10 is different from the one defined in the unnamed namespace in Display 11.9

11.Hello from unnamed.

Hello from Sally.

Hello from unnamed.

12.Outer.

Inner.

Inner.

PROGRAMMING PROJECTS

1 This exercise is intended to illustrate namespaces and separate compilation in your develop-ment environdevelop-ment You should use the developdevelop-ment environdevelop-ment you regularly use in this course for this exercise In a file f.h, place a declaration of void f( ) in namespace A In file g.h, place a declaration of void g( ) in namespace A In files f.cpp and g.cpp, place the definitions of void f( ) and void g( ), respectively Place the definitions of void f( ) and void g( ) in namespace A The functions can do anything you want, but to keep track of execution include something like

cout <<" Function_Name called" << endl;

where Function_Name is the name of the particular function In another file, main.cpp, put your main function, #include the minimum collection of files to provide access to the names from namespace A In your main function call the functions f then g Compile, link, and execute using your development environment To provide access to names in namespaces, you may use local using declarations such as:

using std::cout;

or use local using directives such as:

using namespace std;

inside a block, or qualify names using the names of namespaces, such as std::cout You may not use global namespace directives such as the following which are not in a block and apply to the entire file:

using namespace std;

Of course you must handle namespace A and function names f and g, in addition to possi-bly std and cout

After doing the above, write a one page description of how to create and use namespaces and separate compilation in your environment

Trang 2

498 Separate Compilation and Namespaces

2 Obtain the source code for the PFArrayD class and the demonstration program from Dis-plays 10.10, 10.11, and 10.10 Modify this program to use namespaces and separate com-pilation Put the class definition and other function declarations in one file Place the implementations in a separate file Distribute the namespace definition across the two files Place the demonstration program in a third file To provide access to names in namespaces, you may use local using declarations such as:

using std::cout;

or use local using directives such as:

using namespace std;

inside a block, or qualify names using the names of namespaces, such as std::cout You may not use global namespace directives such as the following which are not in a block and apply to the entire file:

using namespace std;

3 Extend the Programming Project 1 from Chapter 10 in which you implemented a two dimensional array class by placing the class definition and implementation in a namespace, then providing access to the names in the namespace Test your code To provide access to names in namespaces, you may use local using declarations such as

using std::cout;

or use local using directives such as:

using namespace std;

inside a block, or qualify names using the names of namespaces, such as std::cout You may not use global namespace directives such as the following which are not in a block and apply to the entire file:

using namespace std;

1.7

For additional online

Programming Projects,

click the CodeMate icons

below

Trang 3

12 Streams and File I/O

12.1 I/O STREAMS 501

File I/O 501 Pitfall: Restrictions on Stream Variables 506 Appending to a File 506

Tip: Another Syntax for Opening a File 508 Tip: Check That a File Was Opened Successfully 509 Character I/O 512

Checking for the End of a File 513

12.2 TOOLS FOR STREAM I/O 517

File Names as Input 517 Formatting Output with Stream Functions 518 Manipulators 521

Saving Flag Settings 523 More Output Stream Member Functions 524 Example: Cleaning Up a File Format 525 Example: Editing a Text File 528

12.3 STREAM HIERARCHIES: A PREVIEW OF INHERITANCE 528

Inheritance among Stream Classes 528 Example: Another newLine Function 533

12.4 Random Access to Files 536

CHAPTER SUMMARY 538 ANSWERS TO SELF-TEST EXERCISES 539 PROGRAMMING PROJECTS 541

Trang 4

12 Streams and File I/O

Fish say, they have their stream and pond;

But is there anything beyond?

Rupert Brooke, Heaven (1913)

As a leaf is carried by a stream, whether the stream ends in a lake or in the sea, so too is the output of your program carried by

a stream not knowing if the stream goes to the screen or to a file.

Washroom Wall of a Computer Science Department (1995)

INTRODUCTION

Input is delivered to your program and output from your program is delivered

to the output device via special objects known as streams The term stream is supposed to convey the idea that the output is streamed to or from your pro-gram without your propro-gram being aware (or at least not very aware) of where the input data came from or where the output data goes This should, and does, mean that file input is handled in essentially the same way as the key-board input we have been using up to now and that file output is handled in essentially the same way as screen output

File I/O makes a small but essential use of inheritance, which is not covered until Chapter 14 However, we have placed this chapter before the inheritance chapter because programmers often want to start using file I/O early There-fore this chapter includes a brief introduction to what few inheritance details are needed for file I/O

You may cover this chapter anytime after covering the material of Chapters

1 to 4 and 6 to 9; in other words, you may cover this chapter before Chapters

5, 10, and 11 Enough material to allow you to do simple file I/O can be cov-ered even before reading all those chapters The basic elements of file I/O, which are discussed in Section 12.1, may be covered anytime after reading Chapters 1 to 4, Chapter 6, and the subsection of Chapter 9 entitled “The Member Functions get and put.” That subsection is self-contained and does not require reading any other parts of Chapter 9 All of Section 12.2, except for the subsection entitled “File Names as Input”may also be read after read-ing only Chapters 1 to 4, Chapter 6, and the subsection of Chapter 9 entitled

“The Member Functions get and put.”

If you have not read Chapter 11 on namespaces, you may want to review the subsection of Chapter 1 on namespaces

Trang 5

I/O Streams 501

I/O Streams

Good Heavens! For more than forty years I have been speaking prose without knowing it.

Molière, Le Bourgeois Gentilhomme

A stream is a flow of characters (or other kind of data) If the flow is into your

pro-gram, the stream is called an input stream If the flow is out of your program, the

stream is called an output stream If the input stream flows from the keyboard, then

your program will take input from the keyboard If the input stream flows from a file,

then your program will take its input from that file Similarly, an output stream can go

to the screen or to a file

Although you may not realize it, you have already been using streams in your

pro-grams The cin that you have already used is an input stream connected to the

key-board, and cout is an output stream connected to the screen These two streams are

automatically available to your program as long as it has both an include directive that

names the header file <iostream> and a using directive for the std namespace You can

define other streams that come from or go to files; once you have defined them, you

can use them in your program in the same way you use the streams cin and cout For

example, suppose your program defines a stream called inStream that comes from

some file (We’ll tell you how to define it shortly.) You can then fill an int variable

named theNumber with a number from this file by using the following in your program:

int theNumber;

inStream >> theNumber;

Similarly, if your program defines an output stream named outStream that goes to

another file, then you can output the value of the variable theNumber to this other file

The following will output the string "theNumber is " followed by the contents of the

variable theNumber to the output file that is connected to the stream outStream:

outStream << "theNumber is " << theNumber << endl;

Once the streams are connected to the desired files, your program can do file I/O the

same way it does I/O using the keyboard and screen

FILE I/O

The files we will use for I/O in this chapter are text files; that is, they are the same kind

of files as those that contain your C++ programs

When your program takes input from a file, it is said to be reading from the file;

when your program sends output to a file, it is said to be writing to the file There are

other ways of reading input from a file, but the method given in this subsection reads

the file from the beginning to the end (or as far as the program gets before ending)

12.1

stream input stream output stream

cin and

cout are streams

reading and writing

Trang 6

502 Streams and File I/O

Using this method, your program is not allowed to back up and read anything in the file a second time This is exactly what happens when your program takes input from the keyboard, so it should not seem new or strange (As we will see, your program can reread a file starting from the beginning of the file, but this is starting over, not backing up.) Similarly, for the method presented here, your program writes output into a file starting at the beginning of the file and proceeding forward Your program is not allowed to back up and change any output that it has previously written to the file This

is exactly what happens when your program sends output to the screen: You can send more output to the screen, but you cannot back up and change the screen output The way that you get input from a file into your program or send output from your pro-gram into a file is to connect your propro-gram to the file by means of a stream

To send output to a file, your program must first connect the file to a (stream) object

of the class ofstream To read input from a file, your program must first connect the file to a (stream) object of the class ifstream The classes ifstream and ofstream are defined in the <fstream> library and placed in the std namespace Thus, to do both file input and file output, your program would contain

#include <fstream>

using namespace std;

or

#include <fstream>

using std::ifstream;

using std::ofstream;

A stream must be declared just as you would declare any other class variable Thus, you can declare inStream to be an input stream for a file and outStream to be an out-put stream for another file as follows:

ifstream inStream;

ofstream outStream;

Stream variables, such as inStream and outStream declared above, must each be connected to a file This is called opening the file and is done with the member func-tion named open For example, suppose you want the input stream inStream con-nected to the file named infile.txt Your program must then contain the following before it reads any input from this file:

inStream.open("infile.txt");

You can specify a pathname (a directory or folder) when giving the file name The details of how to specify a pathname vary a little from system to system, so consult with

a local guru for the details (or do a little trial-and-error programming) In our examples

we will use simple file names, which assumes that the file is in the same directory (folder) as the one in which your program is running

<fstream>

declaring

streams

connecting a

stream to a file

open

pathnames

Trang 7

I/O Streams 503

Once you have declared an input stream variable and connected it to a file using the

open function, your program can take input from the file using the extraction operator,

>>, with the input stream variable used the same way as cin For example, the following

reads two input numbers from the file connected to inStream and places them in the

variables oneNumber and anotherNumber:

int oneNumber, anotherNumber;

inStream >> oneNumber >> anotherNumber;

An output stream is opened (that is, connected to a file) in the same way as just

described for input streams For example, the following declares the output stream

out-Stream and connects it to the file named outfile.txt:

ofstream outStream;

outStream.open("outfile.txt");

When used with a stream of type ofstream, the member function open will create the

output file if it does not already exist If the output file already exists, the member

func-tion open will discard the contents of the file so that the output file is empty after the

call to open (We will discuss other ways of opening a file a bit later in this chapter.)

After a file is connected to the stream outStream with a call to open, the program

can send output to that file using the insertion operator << For example, the following

writes two strings and the contents of the variables oneNumber and anotherNumber to

the file that is connected to the stream outStream (which in this example is the file

named outfile.txt):

outStream << "oneNumber = " << oneNumber

<< " anotherNumber = " << anotherNumber;

Notice that when your program is dealing with a file, it is as if the file had two

names One is the usual name for the file that is used by the operating system, which is

the external file name In our sample code the external file names were infile.txt

and outfile.txt The external file name is in some sense the “real name” for the file

The conventions for spelling these external file names vary from one system to another

The names infile.txt and outfile.txt that we used in our examples may or may not

look like file names on your system You should name your files following whatever

O VERLOADING OF >> AND << A PPLIES TO F ILES

As we pointed out in Chapter 8, if you overload >> and << , then those overloadings apply to file

input and output streams the same as they apply to cin and cout (If you have not yet read

Chapter 8, you can ignore this remark It will be repeated for you in Chapter 8.)

external file name

Trang 8

504 Streams and File I/O

conventions are used on your operating system Although the external file name is the real name for the file, it is typically used only once in a program The external file name

is given as an argument to the function open, but after the file is opened, the file is always referred to by naming the stream that is connected to the file Thus, within your program, the stream name serves as a second name for the file

The sample program in Display 12.1 reads three numbers from one file and writes their sum, as well as some text, to another file

Every file should be closed when your program is finished getting input from the

file or sending output to the file Closing a file disconnects the stream from the file A file is closed with a call to the function close The following lines from the program in Display 12.1 illustrate how to use the function close:

inStream.close( );

outStream.close( );

Notice that the function close takes no arguments If your program ends normally but without closing a file, the system will automatically close the file for you However, it is good to get in the habit of closing files for at least two reasons First, the system will only close files for you if your program ends normally If your program ends abnor-mally due to an error, the file will not be closed and may be left in a corrupted state If your program closes files as soon as it is finished with them, file corruption is less likely Second, you may want your program to send output to a file and later read that output back into the program To do this, your program should close the file after it is finished writing to the file, and then reopen the file with an input stream (It is possible to open

a file for both input and output, but this is done in a slightly different way.)

A less commonly used member function, but one you may eventually need, is

flush, which is a member function of every output stream For reasons of efficiency,

output is often buffered—that is, temporarily stored someplace—before it is actually

written to a file The member function flush flushes the output stream so that all out-put that may have been buffered is physically written to the file An invocation of

close automatically invokes flush, so you very seldom need to use flush The syntax for flush is indicated by the following example:

outStream.flush( );

A F ILE H AS T WO N AMES

Every input and every output file used by your program has two names The external file name is the real name of the file, but it is used only in the call to the member function open , which con-nects the file to a stream After the call to open , you always use the stream name as the name of the file.

close

Trang 9

I/O Streams 505

Display 12.1 Simple File Input/Output

1 //Reads three numbers from the file infile.txt, sums the numbers,

2 //and writes the sum to the file outfile.txt.

3 #include <fstream>

4 using std::ifstream;

5 using std::ofstream;

6 using std::endl;

7 int main( )

8 {

9 ifstream inStream;

10 ofstream outStream;

11 inStream.open("infile.txt");

12 outStream.open("outfile.txt");

13 int first, second, third;

14 inStream >> first >> second >> third;

15 outStream << "The sum of the first 3\n"

16 << "numbers in infile.txt\n"

17 << "is " << (first + second + third)

18 << endl;

19 inStream.close( );

20 outStream.close( );

21 return 0;

22 }

S AMPLE D IALOGUE

There is no output to the screen and no input from the keyboard.

infile.txt

(Not changed by program)

1

2

3

4

outfile.txt

(After program is run) The sum of the first 3 numbers in infile.txt

is 6

A better version of this program is given in Display 12.3.

Trang 10

506 Streams and File I/O

You declare a stream variable (one of type ifstream or ofstream ) in the usual way, but these variables cannot be used in some of the ways that other variables are used You cannot use an assignment statement to assign a value to a stream variable You can have a parameter of a stream type ( ifstream , ofstream , or any other stream type), but it must be a call-by-reference parameter It cannot be a call-by-value parameter.

APPENDING TO A FILE

When sending output to a file, your code must first use the member function open to open a file and connect it to a stream of type ofstream The way we have done this thus far (with a single argument for the file name) always yields an empty file If a file of the specified name already exists, its old contents are lost There is an alternative way to open a file so that the output from your program will be appended to the file after any data already in the file

To append your output to a file named "important.txt", you would use a two-argument version of open, as illustrated by the following:

ofstream outStream;

outStream.open("important.txt", ios::app);

If the file "important.txt" does not exist, this will create an empty file with that name

to receive your program’s output; if the file already exists, then all the output from your program will be appended to the end of the file, so that old data in the file is not lost This is illustrated in Display 12.2

The second argument ios::app is a defined constant in the class ios The class ios

is defined in the <iostream> library (and also in some other stream libraries) The defi-nition of the class ios is placed in the std namespace, so either of the following will make ios (and hence ios::app) available to your program:

#include <iostream>

using namespace std;

or

#include <iostream>

using std::ios;

ios::app

Ngày đăng: 04/07/2014, 05:21

TỪ KHÓA LIÊN QUAN