Summary

Section 14.1 Introduction

  • Files are used for data persistence (p. 616)—permanent retention of data.

  • Computers store files on secondary storage devices (p. 616), such as hard disks, CDs, DVDs, flash memory and tapes.

Section 14.2 Files and Streams

  • C++ views each file simply as a sequence of bytes.

  • Each file ends either with an end-of-file marker or at a specific byte number recorded in a system-maintained, administrative data structure.

  • When a file is opened, an object is created, and a stream is associated with the object.

  • To perform file processing in C++, headers <iostream> and <fstream> must be included.

  • Header <fstream> includes the definitions for the stream class templates basic_ifstream (for file input), basic_ofstream (for file output) and basic_fstream (for file input and output).

  • Each class template has a predefined template specialization that enables char I/O. The <fstream> library provides typedef aliases for these template specializations. The typedef ifstream represents a specialization of basic_ifstream that enables char input from a file. The typedef ofstream represents a specialization of basic_ofstream that enables char output to files. The typedef fstream represents a specialization of basic_fstream that enables char input from, and output to, files.

  • The file-processing templates derive from class templates basic_istream, basic_ostream and basic_iostream, respectively. Thus, all member functions, operators and manipulators that belong to these templates also can be applied to file streams.

Section 14.3 Creating a Sequential File

  • C++ imposes no structure on a file; you must structure files to meet the application’s requirements.

  • A file can be opened for output when an ofstream object is created. Two arguments are passed to the object’s constructor—the filename (p. 618) and the file-open mode (p. 618).

  • For an ofstream (p. 618) object, the file-open mode can be either ios::out (p. 618) to output data to a file or ios::app (p. 618) to append data to the end of a file. Existing files opened with mode ios::out are truncated (p. 619). If the specified file does not exist, the ofstream object creates the file using that filename.

  • By default, ofstream objects are opened for output.

  • An ofstream object can be created without opening a specific file—a file can be attached to the object later with member function open (p. 619).

  • The overloaded operator ! for a stream determines whether a stream was opened correctly. This operator can be used in a condition that returns true if either the failbit or the badbit is set for the stream on the open operation.

  • The overloaded operator bool for a stream converts the stream to true or false. If the failbit or badbit has been set for a stream, false is returned.

  • Entering the end-of-file indicator sets the failbit for cin.

  • The operator bool function can be used to test an input object for end-of-file instead of calling the eof member function explicitly on the input object.

  • When a stream object’s destructor is called, the corresponding stream is closed. You also can close the stream object explicitly, using the stream’s close member function.

Section 14.4 Reading Data from a Sequential File

  • Files store data so it may be retrieved for processing when needed.

  • Creating an ifstream object opens a file for input. The ifstream constructor can receive the filename and the file open mode as arguments.

  • Open a file for input only if the file’s contents should not be modified.

  • Objects of class ifstream are opened for input by default.

  • An ifstream object can be created without opening a specific file; a file can be attached to it later.

  • To retrieve data sequentially from a file, programs normally start reading from the beginning of the file and read all the data consecutively until the desired data is found.

  • The member functions for repositioning the file-position pointer (p. 623) are seekg (“seek get” ; p. 623) for istream and seekp (“seek put” ; p. 623) for ostream. Each istream has a “get pointer,” which indicates the byte number in the file from which the next input is to occur, and each ostream has a “put pointer,” which indicates the byte number in the file at which the next output should be placed.

  • The argument to seekg is a long integer. A second argument can be specified to indicate the seek direction (p. 623), which can be ios::beg (the default; p. 623) for positioning relative to the beginning of a stream, ios::cur (p. 623) for positioning relative to the current position in a stream or ios::end (p. 623) for positioning relative to the end of a stream.

  • The file-position pointer (p. 623) is an integer value that specifies the location in the file as a number of bytes from the file’s starting location (i.e., the offset (p. 623) from the beginning of the file).

  • Member functions tellg (p. 623) and tellp (p. 623) are provided to return the current locations of the “get” and “put” pointers, respectively.

Section 14.5 C++14: Reading and Writing Quoted Text

  • C++14’s stream manipulator quoted (p. 627; header <iomanip>) enables a program to read quoted text from a stream, including any white space characters in the quoted text, and discards the double-quote delimiters.

  • You also can use quoted to write quoted text to a stream.

Section 14.6 Updating Sequential Files

  • Data that is formatted and written to a sequential file cannot be modified without the risk of destroying other data in the file. The problem is that records can vary in size.

Section 14.7 Random-Access Files

  • Sequential files are inappropriate for instant-access applications (p. 628), in which a particular record must be located immediately.

  • Instant access is made possible with random-access files (p. 628). Individual records of a random-access file can be accessed directly (and quickly) without having to search other records.

  • The easiest method to format files for random access is to require that all records in a file be of the same fixed length. Using same-size, fixed-length records makes it easy for a program to calculate (as a function of the record size and the record key) the exact location of any record relative to the beginning of the file.

  • Data can be inserted into a random-access file without destroying other data in the file.

  • Data stored previously can be updated or deleted without rewriting the entire file.

Section 14.8 Creating a Random-Access File

  • The ostream member function write outputs a fixed number of bytes, beginning at a specific location in memory, to the specified stream. Function write writes the data at the location in the file specified by the “put” file-position pointer.

  • The istream member function read (p. 629) inputs a fixed number of bytes from the specified stream to an area in memory beginning at a specified address. If the stream is associated with a file, function read inputs bytes at the location in the file specified by the “get” file-position pointer.

  • Function write treats its first argument as a group of bytes by viewing the object in memory as a const char*, which is a pointer to a byte (remember that a char is one byte). Starting from that location, function write outputs the number of bytes specified by its second argument. The istream function read can subsequently be used to read the bytes back into memory.

  • The reinterpret_cast operator (p. 629) converts a pointer of one type to a pointer of an unrelated type.

  • A reinterpret_cast is performed at compile time and does not change the value of the object to which its operand points.

  • A program that reads unformatted data must be compiled and executed on a system compatible with the program that wrote the data—different systems may represent internal data differently.

  • Objects of class string do not have uniform size, rather they use dynamically allocated memory to accommodate strings of various lengths.

Section 14.9 Writing Data Randomly to a Random-Access File

  • Multiple file-open modes are combined by separating each open mode from the next with the bitwise inclusive-OR operator (|).

  • The string member function size (p. 632) gets the length of a string.

  • The file-open mode ios::binary (p. 633) indicates that a file should be opened in binary mode.

Section 14.10 Reading from a Random-Access File Sequentially

  • A function that receives an ostream parameter can receive any ostream object (such as cout) or any object of a derived class of ostream (such as an object of type ofstream) as an argument. This means that the same function can be used, for example, to perform output to the standard-output stream and to a file stream without writing separate functions.

Section 14.12 Object Serialization

  • When object data members are output to a disk file, we lose the object’s type information. We store only the values of the object’s attributes, not type information, on the disk. If the program that reads this data knows the object type to which the data corresponds, the program can read the data into an object of that type.

  • A so-called serialized object (p. 644) is an object represented as a sequence of bytes that includes the object’s data as well as information about the object’s type and the types of data stored in the object. A serialized object can be read from the file and deserialized (p. 644).

  • The open-source Boost Libraries provide support for serializing objects (p. 644) in text, binary and extensible markup language (XML) formats.

Self-Review Exercises

  1. 14.1 (Fill in the Blanks) Fill in the blanks in each of the following:

    1. Member function               of the file streams fstream, ifstream and ofstream closes a file.

    2. The ostream member function               is normally used when writing data to a file in random-access applications.

    3. Member function               of the file streams fstream, ifstream and ofstream opens a file.

    4. The istream member function               is normally used when reading data from a file in random-access applications.

    5. Member functions               and               of istream and ostream set the file-position pointer to a specific location in an input or output stream, respectively.

  2. 14.2 (True or False) State which of the following are true and which are false. If false, explain why.

    1. Member function read cannot be used to read data from the input object cin.

    2. You must create the cin, cout, cerr and clog objects explicitly.

    3. A program must call function close explicitly to close a file associated with an ifstream, ofstream or fstream object.

    4. If the file-position pointer points to a location in a sequential file other than the beginning of the file, the file must be closed and reopened to read from the beginning of the file.

    5. The ostream member function write can write to standard-output stream cout.

    6. Data in sequential files always is updated without overwriting nearby data.

    7. Searching all records in a random-access file to find a specific record is unnecessary.

    8. Records in random-access files must be of uniform length.

    9. Member functions seekp and seekg must seek relative to the beginning of a file.

  3. 14.3 Assume that each of the following statements applies to the same program.

    1. Write a statement that opens file oldmast.dat for input; use an ifstream object called inOldMaster.

    2. Write a statement that opens file trans.dat for input; use an ifstream object called inTransaction.

    3. Write a statement that opens file newmast.dat for output (and creation); use ofstream object outNewMaster.

    4. Write a statement that reads a record from the file oldmast.dat. The record consists of integer accountNumber, string name (containing spaces) and floating-point currentBalance. Use ifstream object inOldMaster.

    5. Write a statement that reads a record from the file trans.dat. The record consists of integer accountNum and floating-point dollarAmount. Use ifstream object inTransaction.

    6. Write a statement that writes a record to the file newmast.dat. The record consists of integer accountNum, string name, and floating-point currentBalance. Use ofstream object outNewMaster.

  4. 14.4 Find the error(s) and show how to correct it (them) in each of the following.

    1. File payables.dat referred to by ofstream object outPayable has not been opened.

      
      outPayable << account << company << amount << endl;
      
    2. The following statement should read a record from the file payables.dat. The ifstream object inPayable refers to this file, and ifstream object inReceivable refers to the file receivables.dat.

      
      inReceivable >> account >> company >> amount;
      
    3. The file tools.dat should be opened to add data to the file without discarding the current data.

      
      ofstream outTools("tools.dat", ios::out);
      

Answers to Self-Review Exercises

  1. 14.1

    1. close.

    2. write.

    3. open.

    4. read.

    5. seekg, seekp.

  2. 14.2

    1. False. Function read can read from any input stream object derived from istream.

    2. False. These four streams are created automatically for you. The <iostream> header must be included in a file to use them. This header includes declarations for each predefined stream object.

    3. False. The files will be closed when destructors for ifstream, ofstream or fstream objects execute when the stream objects go out of scope or before program execution terminates, but it’s a good programming practice to close all files explicitly with close once they’re no longer needed.

    4. False. Member functions seekp and seekg can be used to reposition the “put” or “get” file-position pointers, respectively, to the beginning of the file.

    5. True.

    6. False. In most cases, sequential file records are not of uniform length. Therefore, it’s possible that updating a record will cause other data to be overwritten.

    7. True.

    8. False. Records in a random-access file normally are of uniform length.

    9. False. It’s possible to seek from the beginning of the file, from the end of the file and from the current position in the file.

  3. 14.3

    1. ifstream inOldMaster{"oldmast.dat", ios::in};

    2. ifstream inTransaction{"trans.dat", ios::in};

    3. ofstream outNewMaster{"newmast.dat", ios::out};

    4. inOldMaster >> accountNumber >> quoted(name) >> currentBalance;

    5. inTransaction >> accountNum >> dollarAmount;

    6. outNewMaster << accountNum << " " << name << " " << currentBalance;

  4. 14.4

    1. Error: The file payables.dat has not been opened before the attempt is made to output data to the stream.

      Correction: Use ofstream function open to open payables.dat for output.

    2. Error: The incorrect ifstream object is being used to read a record from the file named payables.dat.

      Correction: Use ifstream object inPayable to refer to payables.dat.

    3. Error: The file’s contents are discarded because the file is opened for output (ios::out).

      Correction: To add data to the file, open the file either for updating (ios::ate) or for appending (ios::app).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset