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

10 516 1
Absolute C++ (4th Edition) part 53 pdf

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

Thông tin tài liệu

Tools for Stream I/O 527 Display 12.7 Formatting Output (part 2 of 2) 44 cout << "End of program.\n"; 45 return 0; 46 } 47 //Uses <iostream>, <fstream>, and <iomanip>: 48 void makeNeat(ifstream& messyFile, ofstream& neatFile, 49 int numberAfterDecimalpoint, int fieldWidth) 50 { 51 neatFile.setf(ios::fixed); 52 neatFile.setf(ios::showpoint); 53 neatFile.setf(ios::showpos); 54 neatFile.precision(numberAfterDecimalpoint); 55 cout.setf(ios::fixed); 56 cout.setf(ios::showpoint); 57 cout.setf(ios::showpos); 58 cout.precision(numberAfterDecimalpoint); 59 double next; 60 while (messyFile >> next) 61 { 62 cout << setw(fieldWidth) << next << endl; 63 neatFile << setw(fieldWidth) << next << endl; 64 } 65 } setf and precision behave the same for a file output stream as they do for cout. Satisfied if there is a next number to read Works the same for file output streams as it does for cout neat.txt (After program is run) +10.37000 -9.89897 +2.31300 -8.95000 +15.00000 +7.33333 +92.87650 -123.75684 S CREEN O UTPUT +10.37000 -9.89897 +2.31300 -8.95000 +15.00000 +7.33333 +92.87650 -123.75684 End of program. rawdata.txt (Not changed by program) 10.37 -9.89897 2.313 -8.950 15.0 7.33333 92.8765 -1.237568432e2 528 Streams and File I/O Example E DITING A T EXT F ILE The program discussed here is a very simple example of text editing applied to files. This program can be used to automatically generate C++ advertising material from existing C advertising mate- rial (in a rather simplistic way). The program takes its input from a file that contains advertising copy that says good things about C and writes similar advertising copy about C++ in another file. The file that contains the C advertising copy is called cad.txt, and the new file that receives the C++ advertising copy is called cppad.txt. The program is shown in Display 12.8. The program simply reads every character in the file cad.txt and copies the characters to the file cppad.txt. Every character is copied unchanged, except that when the uppercase letter ’C’ is read from the input file, the program writes the string "C++" to the output file. This program assumes that whenever the letter ’C’ occurs in the input file, it names the C programming lan- guage; so this change is exactly what is needed to produce the updated advertising copy. Notice that the line breaks are preserved when the program reads characters from the input file and writes the characters to the output file. The newline character ’\n’ is treated just like any other character. It is read from the input file with the member function get, and it is written to the output file using the insertion operator, <<. We must use the member function get to read the input (rather than the extraction operator, >>) because we want to read whitespace. Stream Hierarchies: A Preview of Inheritance One very useful way to organize classes is by means of the “derived from” relationship. When we say that one class is derived from another class we mean that the derived class was obtained from the other class by adding features. For example, the class of input- file streams is derived from the class of all input streams by adding additional member functions such as open and close. The stream cin belongs to the class of all input streams, but does not belong to the class of input-file streams because cin has no mem- ber functions named open and close. This section introduces the notion of a derived class as a way to think about and organize the predefined stream classes. (Chapter 14 shows how to use the idea of a derived class to define classes of your own.) ■ INHERITANCE AMONG STREAM CLASSES Both the predefined stream cin and an input-file stream are input streams. So in some sense they are similar. For example, you can use the extraction operator, >>, with either kind of stream. On the other hand, an input-file stream can be connected to a file using the member function open, but the stream cin has no member function named open. An input-file stream is a similar but different kind of stream than cin. An input-file stream is of type ifstream. The object cin is an object of the class istream (spelled without the ’f’). The classes ifstream and istream are different but closely related types. The class ifstream is a derived class of the class istream. Let’s see what that means. 12.3 Stream Hierarchies: A Preview of Inheritance 529 Display 12.8 Editing a File of Text (part 1 of 2) 1 //Program to create a file called cplusad.txt that is identical to the file 2 //cad.txt except that all occurrences of ’C’ are replaced by "C++". Assumes 3 //that the uppercase letter ’C’ does not occur in cad.txt except as the 4 //name of the C programming language. 5 #include <fstream> 6 #include <iostream> 7 #include <cstdlib> 8 using std::ifstream; 9 using std::ofstream; 10 using std::cout; 11 void addPlusPlus(ifstream& inStream, ofstream& outStream); 12 //Precondition: inStream has been connected to an input file with open. 13 //outStream has been connected to an output file with open. 14 //Postcondition: The contents of the file connected to inStream have been 15 //copied into the file connected to outStream, but with each ’C’ replaced 16 //by "C++". (The files are not closed by this function.) 17 int main( ) 18 { 19 ifstream fin; 20 ofstream fout; 21 cout << "Begin editing files.\n"; 22 fin.open("cad.txt"); 23 if (fin.fail( )) 24 { 25 cout << "Input file opening failed.\n"; 26 exit(1); 27 } 28 fout.open("cppad.txt"); 29 if (fout.fail( )) 30 { 31 cout << "Output file opening failed.\n"; 32 exit(1); 33 } 34 addPlusPlus(fin, fout); 530 Streams and File I/O Display 12.8 Editing a File of Text (part 2 of 2) 35 fin.close( ); 36 fout.close( ); 37 cout << "End of editing files.\n"; 38 return 0; 39 } 40 void addPlusPlus(ifstream& inStream, ofstream& outStream) 41 { 42 char next; 43 inStream.get(next); 44 while (! inStream.eof( )) 45 { 46 if (next == ’C’) 47 outStream << "C++"; 48 else 49 outStream << next; 50 inStream.get(next); 51 } 52 } C is one of the world’s most modern programming languages. There is no language as versatile as C, and C is fun to use. C++ is one of the world’s most modern programming languages. There is no language as versatile as C++, and C++ is fun to use. cad.txt (Not changed by program) cppad.txt (After program is run) Begin editing files. End of editing files. S CREEN O UTPUT Stream Hierarchies: A Preview of Inheritance 531 When we say that some class D is a derived class of some other class B, it means that class D has all the features of class B but it also has added features. For example, any stream of type istream (without the ’f’) can be used with the extraction operator, >>. The class ifstream (with the ’f’) is a derived class of the class istream, so an object of type ifstream can be used with the extraction operator, >>. An object of the class ifstream has all the properties of an object of type istream. In particular, an object of the class ifstream is also an object of type istream. However, ifstream has added features so that you can do more with an object of type ifstream than you can with an object that is only of type istream. For example, one added feature is that a stream of type ifstream can be used with the function open. The stream cin is only of type istream and not of type ifstream. You cannot use cin with the function open. Notice that the relationship between the classes ifstream and istream is not symmetric. Every object of type ifstream is of type istream (a file input stream is an input stream), but an object of type istream need not be of type ifstream (the object cin is of type istream but not of type ifstream). The idea of a derived class is really quite common. An example from everyday life may help to make the idea clearer. The class of all convertibles, for instance, is a derived class of the class of all automobiles. Every convertible is an automobile, but a convert- ible is not just an automobile. A convertible is a special kind of automobile with special properties that other kinds of automobiles do not have. If you have a convertible, you can lower the top so that the car is open. (You might say that a convertible has an “ open” function as an added feature.) If D is a derived class of the class B, then every object of type D is also of type B. A convertible is also an automobile. A file input stream (object of the class ifstream) is also an input stream (also an object of the class istream). So, if we use istream as the type for a function parameter, rather than using ifstream, then more objects can be plugged in for the parameter. Consider the following two function definitions, which differ only in the type of the parameter (and the function name): void twoSumVersion1(ifstream& sourceFile)//ifstream with an ’f’ { int n1, n2; sourceFile >> n1 >> n2; cout << n1 << " + " << n2 << " = " << (n1 + n2) << endl; } and void twoSumVersion2(istream& sourceFile)//istream without an ’f’ { int n1, n2; sourceFile >> n1 >> n2; cout << n1 << " + " << n2 << " = " << (n1 + n2) << endl; } derived class 532 Streams and File I/O With twoSumVersion1, the argument must be of type ifstream. So if fileIn is a file input stream connected to a file, then twoSumVersion1(fileIn); is legal, but twoSumVersion1(cin); //ILLEGAL is not legal, because cin is not of type ifstream. The object cin is only a stream and only of type istream; cin is not a file input stream. The function twoSumVersion2 is more versatile. Both of the following are legal: twoSumVersion2(fileIn); twoSumVersion2(cin); The moral is clear: Use istream, not ifstream, as a parameter type whenever you can. When choosing a parameter type, use the most general type you can. (To draw a real-life analogy: You might prefer to own a convertible, but you would not want a garage that could only hold a convertible. What if you borrowed a sedan from a friend? You’d still want to be able to park the sedan in your garage.) You cannot always use the parameter type istream instead of the parameter type ifstream. If you define a function with a parameter of type istream, then that param- eter can only use istream member functions. In particular, it cannot use the functions open and close. If you cannot keep all calls to the member functions open and close outside the function definition, then you must use a parameter of type ifstream. So far we have discussed two classes for input streams: istream and its derived class ifstream. The situation with output streams is similar. Chapter 1 introduced the out- put streams cout and cerr, which are in the class ostream. This chapter introduced the file output streams, which are in the class ofstream (with an ’f’). The class ostream is the class of all output streams. The streams cout and cerr are of type ostream, but not of type ofstream. In contrast to cout or cerr, an output-file stream is declared to be of type ofstream. The class ofstream of output-file streams is a derived class of the class ostream. For example, the following function writes the word "Hello" to the output stream given as its argument. void sayHello(ostream& anyOutStream) { anyOutStream << "Hello"; } The first of the following calls writes "Hello" to the screen; the second writes "Hello" to the file with the external file name afile.txt. ofstream fout; fout.open("afile.txt"); sayHello(cout); sayHello(fout); ostream and ofstream Stream Hierarchies: A Preview of Inheritance 533 Example Note that an output-file stream is of type ofstream and of type ostream. Derived classes are often discussed using the metaphor of inheritance and family relationships. If class D is a derived class of class B, then class D is called a child of class B and class B is called a parent of class D. The derived class is said to inherit the mem- ber functions of its parent class. For example, every convertible inherits the fact that it has four wheels from the class of all automobiles, and every input-file stream inherits the extraction operator, >>, from the class of all input streams. This is why the topic of derived classes is often called inheritance. A NOTHER newLine F UNCTION As an example of how you can make a stream function more versatile, consider the function new- Line that we defined in Display 9.2. That function works only for input from the keyboard, which is input from the predefined stream cin. The function newLine in Display 9.2 has no arguments. Below we have rewritten the function newLine so that it has a formal parameter of type istream for the input stream: //Uses <iostream>: void newLine(istream& inStream) { char symbol; do { M AKING S TREAM P ARAMETERS V ERSATILE If you want to define a function that takes an input stream as an argument and you want that argument to be cin in some cases and an input-file stream in other cases, then use a formal parameter of type istream (without an ’f’). However, an input-file stream, even if used as an argument of type istream, must still be declared to be of type ifstream (with an ’f’). Similarly, if you want to define a function that takes an output stream as an argument and you want that argument to be cout in some cases and an output-file stream in other cases, then use a formal parameter of type ostream. However, an output-file stream, even if used as an argument of type ostream, must still be declared to be of type ofstream (with an ’f’). You cannot open or close a stream parameter of type istream or ostream. Open these objects before passing them to your function and close them after the function call. The stream classes istream and ostream are defined in the iostream library and placed in the std namespace. One way to make them available to your code is the following: #include <iostream> using std::istream; using std::ostream; inheritance child parent 534 Streams and File I/O inStream.get(symbol); } while (symbol != ’\n’); } Now, suppose your program contains this new version of the function newLine. If your program is taking input from an input stream called fin (which is connected to an input file), the follow- ing will discard all the input left on the line currently being read from the input file: newLine(fin); If your program is also reading some input from the keyboard, the following will discard the remainder of the input line that was typed in at the keyboard: newLine(cin); If your program has only the above rewritten version of newLine, which takes a stream argument such as fin or cin, you must always give the stream name, even if the stream name is cin. But thanks to overloading, you can have both versions of the function newLine in the same program: the version with no arguments that is given in Display 9.2 and the version with one argument of type istream that we just defined. In a program with both definitions of newLine, the following two calls are equivalent: newLine(cin); and newLine( ); You do not really need two versions of the function newLine. The version with one argument of type istream can serve all your needs. However, many programmers find it convenient to have a version with no arguments for keyboard input, since keyboard input is used so frequently. An alternative to having two overloaded versions of the newLine function is to use a default argument (as discussed in Chapter 4). In the following code, we have rewritten the newLine function a third time: //Uses <iostream>: void newLine(istream& inStream = cin) { char symbol; do { inStream.get(symbol); } while (symbol != '\n'); } If we call this function as newLine( ); using both versions of newLine Stream Hierarchies: A Preview of Inheritance 535 Self-Test Exercises the formal parameter takes the default argument cin. If we call this as newLine(fin); the formal parameter takes the argument fin. An alternative to using this newLine function is to use the function ignore, which we discussed in Chapter 9. The function ignore is a member of every input-file stream as well as a member of cin. 13. What is the type of the stream cin? What is the type of the stream cout? 14. Define a function called copyChar that takes one argument that is an input stream. When called, copyChar will read one character of input from the input stream given as its argu- ment and will write that character to the screen. You should be able to call your function using either cin or an input-file stream as the argument to your function copyChar. (If the argument is an input-file stream, then the stream is connected to a file before the function is called, so copyChar will not open or close any files.) For example, the first of the follow- ing two calls to copyChar will copy a character from the file stuff.txt to the screen, and the second will copy a character from the keyboard to the screen: ifstream fin; fin.open("stuff.txt"); copyChar(fin); copyChar(cin); 15. Define a function called copyLine that takes one argument that is an input stream. When called, copyLine reads one line of input from the input stream given as its argument and writes that line to the screen. You should be able to call your function using either cin or an input-file stream as the argument to your function copyLine. (If the argument is an input-file stream, then the stream is connected to a file before the function is called, so copyLine will not open or close any files.) For example, the first of the following two calls to copyLine will copy a line from the file stuff.txt to the screen, and the second will copy a line from the keyboard to the screen: ifstream fin; fin.open("stuff.txt"); copyLine(fin); copyLine(cin); 16. Define a function called sendLine that takes one argument that is an output stream. When called, sendLine reads one line of input from the keyboard and outputs the line to the output stream given as its argument. You should be able to call your function using either cout or an output-file stream as the argument to your function sendLine. (If the ignore 536 Streams and File I/O argument is an output-file stream, then the stream is connected to a file before the function is called, so sendLine will not open or close any files.) For example, the first of the follow- ing calls to sendLine will copy a line from the keyboard to the file morestuf.txt, and the second will copy a line from the keyboard to the screen: ofstream fout; fout.open("morestuf.txt"); cout << "Enter 2 lines of input:\n"; sendLine(fout); sendLine(cout); 17. Is the following statement true or false? If it is false, correct it. In either event, explain it carefully. A function written using a parameter of class ifstream or ofstream can be called with istream or ostream arguments, respectively. Random Access to Files Any time, any where. Common response to a challenge for a confrontation The streams for sequential access to files, which we discussed in the previous sections of this chapter, are the ones most often used for file access in C++. However, some appli- cations that require very rapid access to records in very large databases require some sort of random access to particular parts of a file. Such applications might best be done with specialized database software. But perhaps you are given the job of writing such a pack- age in C++, or perhaps you are just curious about how such things are done in C++. C++ does provide for random access to files so that your program can both read from and write to random locations in a file. This section gives a brief glimpse of this ran- dom access to files. This is not a complete tutorial on random access to files, but will let you know the name of the main stream class used and the important issues you will encounter. If you want to be able to both read and write to a file in C++, you use the stream class fstream that is defined in the <fstream> library. The definition of fstream is placed in the std namespace. Details about opening a file and connecting it to a stream in the class fstream are basically the same as discussed for the classes ifstream and ofstream, except that fstream has a second argument to open. This second argument specifies whether the stream is used for input, output, or both input and output. For example, a program that does both input and output to a file named "stuff" might start as follows: 12.4 . no language as versatile as C, and C is fun to use. C++ is one of the world’s most modern programming languages. There is no language as versatile as C++, and C++ is fun to use. cad.txt (Not changed by. used for file access in C++. However, some appli- cations that require very rapid access to records in very large databases require some sort of random access to particular parts of a file. Such. perhaps you are given the job of writing such a pack- age in C++, or perhaps you are just curious about how such things are done in C++. C++ does provide for random access to files so that your program

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

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan