Previous fileTop of DocumentContentsIndex pageNext file
Apache C++ Standard Library User's Guide

30.5 File Positioning

Iostream support for file positioning operations depends on the character encoding of a particular stream. For fixed-width encodings, such as ASCII or UNICODE, the file stream classes allow a full set of positioning operations comparable to those offered by `C' stdio. The options for variable-width and state-dependent encodings, such as JIS, are limited. For these more complex encodings, the only allowed positioning operations are 'seek to beginning', 'seek to end', or 'seek to a previously known location'. The last option requires that you arrive at and then store a particular position before a seek can be performed. Attempting to seek to an arbitrary offset on a stream with variable-width or state-dependent character encodings has an undefined effect on the file position. Here's an example of the correct way to seek to a position in any file stream, regardless of encoding:

//1Here we output some characters in order to move the file position to some arbitrary location that we'll later seek back to.
//2Now we use the tellp() function to obtain the current file position.
//3Output some more text to move the file position along.
//4Finally, seek back to our previously saved position.

This is the only possible method for seeking to an arbitrary position--that is, a position other than beginning or end of file--in a stream with variable or state-dependent character encoding. Of course, the method also works with fixed-width encodings.

The example above shows one use of two of the output file positioning functions, tellp() and a version of seekp(). An ofstream also has another version of the seekp() function that allows a seek to an arbitrary offset in much the same way that the `C' stdio fseek() function works. This function can be used to seek to the beginning or end of any ofstream, or anywhere else in an ofstream with a fixed-width character encoding. For instance:

//1Seek back two characters. Position at the s in Patches.
//2Seek to beginning of the file.

The first parameter of this function is a value of std::ofstream::off_type, and the second is one of three constants indicating starting position for the seek. These three values correspond to the three possible seek types available with the `C' stdio function fseek(). They are defined in the base class std::ios_base. The table below summarizes the three different kinds of seeks possible with this version of seekp():

Table 35: Possible seeks for seekp 

Type of seek Argument to seekp `C' stdio equivalent

seek relative to beginning of file

ios_base::beg

SEEK_SET

seek relative to end of file

ios_base::end

SEEK_END

seek relative to current position

ios_base::cur

SEEK_CUR

As in the example, passing 0 as the offset with std::ios_base::beg as the seek type seeks to the beginning of the file. Likewise, using 0 with std::ios_base::end seeks to the end of the file. Since the function returns the current position after the seek operation, passing 0 along with std::ios_base::cur gets you the current file position without moving it. This is equivalent to calling the tellp() member function.

ifstream provides the same set of functions but with slightly different names: tellg() instead of tellp(), and seekg(...) instead of seekp(...). The reason for this specialized naming scheme can be seen in the fstream class, which provides both sets of functions so that the input and output streams can be manipulated separately.

30.5.1 How Positioning Works with the Iostream Architecture

If you look at the iostream class definitions, you notice that the seek functions are not defined in these classes. Instead, they are inherited from a base class template: basic_ostream for tellp() and seekp(), and basic_istream for tellg() and seekg(). These functions then call (indirectly, through their public interface) virtual functions in the stream buffer, where seeking is actually implemented. Seek functions for ofstream, ifstream, and fstream actually call pubseekoff() and pubseekpos() in filebuf. The code looks like this:

Calling virtual functions in the stream buffer maintains the fundamental separation of buffer manipulation and I/O from string formatting. While it's not necessary to know this in order to use file seek operations, it is important if you ever need to subclass a stream buffer.



Previous fileTop of DocumentContentsIndex pageNext file