12.2 Reading and Writing Files


12.2 Reading and Writing Files

C++ provides a number of easy-to-use classes to read and write from files on disk. This means programmers can save their data to files, and can then load them back from disk and into memory. To read and write data to files, C++ offers two specific classes-one for reading and one for writing-called std::ifstream and std::ofstream.

Note 

In order to use std::ifstream and std::ofstream, an additional preprocessor include directive must be included to use class code from a different file. This file is fstream. These classes are considered in the following subsections where you'll also notice the additional preprocessor directive.

12.2.1 Writing Data to Files with std::ofstream

Many types of programs will need to save information to disk for permanent storage. For example, a word processor needs to store documents and games need to save their information. Players of a game will naturally want to save their progress, and any saved game file must include a variety of details about the session being saved. A strategy game, for example, will store details about the player's army, how many military units have been developed, which buildings are constructed, how much gold has been collected, and which level has been reached. All of this is stored so players can resume their progress each time they save their game without having to restart the game every time they play. Saving data to files in C++ is achieved through the std::ofstream class, and it works in much the same way as printing text on the screen using std::cout, as demonstrated in the previous chapters.

12.2.2 Creating Files

A std::ofstream object can be created in the standard way other objects are created, or it can be created dynamically using the new keyword. The constructor of the std::ofstream class accepts two arguments: a valid file name for the file to create and an access mode. Consider the following code to create a file named example.txt for writing:

      std::ofstream file ("c:\\example.txt", ios::app); 
Note 

The code will create a new file called example.txt or overwrite an existing file with this name. Notice the "\\" characters, which represent folder paths. Once the file is created, nothing is written to the file yet. This occurs in the next step.

12.2.3 Opening Files

Once a file has been created, it is also opened. This means the file becomes protected so other applications cannot write to the file or change the contents while it is being accessed by your program. To test whether the file is open, the is_open method of std::ofstream can be called, as follows:

      if(file.is_open())      {         //Do some stuff      } 

12.2.4 Writing Data to Files

A file that is opened with std::ofstream can be written to just like text is printed with std::cout, but instead of being printed to the screen, it is printed to the file. The following sample program shows the collection of std::ofstream methods discussed thus far for printing information to a file.

      #include <fstream>      #include <iostream>      int main()      {         std::ofstream file ("c:\\example.txt", ios::app);         if(file.is_open())         {            file<<"hello world in a file\n";            file.close();         }         return 0;      } 

12.2.5 Reading Data from Files with std::ifstream

Whatever information an application can save to a file will be useless unless the application can read back that information at a later time. For example, players who save their game data will, at some time, intend to load that data back so they can resume their games. This process is called reading data, and C++ offers the std::ifstream class to open and read data from an existing file.

12.2.6 Opening Files

Like the std::ofstream class, the std::ifstream class requires the file name of an existing file for reading. Consider the following code to create an std::ifstream object:

      std::ifstream file ("c:\\example.txt"); 

12.2.7 Reading Data

Once an existing file is opened its contents are then protected so other applications cannot delete or change the file while it's being read. Though the file might be open, the contents are still inside the file only; they are not read into memory in one lump. After all, a file could be hundreds and hundreds of megabytes large, and reading all that information into memory in one chunk could crash an application because it is too large for a computer's memory to hold. So it remains the responsibility of an application to collect whatever data it needs from the file in batches, reading segments in at a time as appropriate. There are several methods available to read data from a file, one of which is the read method of std::ifstream. This method reads a specified number of bytes from the file, starting at the beginning, and it loads the contents into a char array.

      #include <fstream>      #include <iostream>      int main()      {         std::ifstream file ("c:\\example.txt");         if(file.is_open())         {            char *buffer;            file.read(buffer, 100);            std::cout<<buffer;            file.close();         }      return 0;      } 

12.2.8 Seeking Data

Although it might seem the read method features everything a programmer needs to read data from a file, it has limitations. Most importantly, data can only be read from the start of the file. Though a programmer may specify the number of bytes to read, the data is still measured relative to the beginning of the file. Seeking solves this problem. The std::ifstream class has the seekg method to position the get pointer within the file. The get pointer refers to the index within the file where reading will begin, and the date is read from left to right.

Typically, when the read method is called, data is read from the beginning of the file. However, the seekg method can be used to change the position at which data is read. The method is overloaded and comes in two forms: It can be passed a position and the get pointer will move there, or it can be passed an offset and a seek direction. The first seekg method is the simplest since it sets the get pointer to a position within the file measured from the beginning, which is 0. The second version of the method accepts a reference point other than the beginning where measuring is to begin. If the get pointer is moved to the end of the file using ios:end, the get pointer is in the rightmost position. It will need to be reversed leftward away from this location before it can read data (because only data to the right of the get pointer is read.) The offset parameter is then used to measure leftward from this reference point. So, if the file pointer began at the end (ios:end) and the offset was 7 (bytes), the get pointer would first be moved to the end of the file, and then reversed 7 bytes away from the end. Consider the following code:

      #include <iostream>      #include <fstream>      using namespace std;      int main ()      {         int length;         char *buffer;         ifstream is;         is.open ("example.txt");         // get length of file:         is.seekg (0, ios::end);         length = is.tellg();         is.seekg (0, ios::beg);         // allocate memory:         buffer = new char [length];         // read data as a block:         is.read (buffer,length);         is.close();      cout.write (buffer,length);      return 0; 




Introduction to Game Programming with C++
Introduction to Game Programming with C++ (Wordware Game Developers Library)
ISBN: 1598220322
EAN: 2147483647
Year: 2007
Pages: 225
Authors: Alan Thorn

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net