Synfire's Guide to C++

9. File I/O

In this chapter I am about to cover a VERY, VERY important topic. File I/O is something that you should know and use! It allows your program to manipulate files to do jobs such as databases, video games, and of course operating systems and compilers. This is a part of C++ that really gets some people because it really isn't very 'user friendly' of a syntax, unlike C's 'openf(HANDLE, "Filename.txt")' style syntax.

In this section we will incorporate another library called fstream.h. This library handles ALL File I/O. This is somewhat of a difficult subject in C++ so I will spend a little while on the workings of each step, then give an example program.

I have broken this section down into four separate parts, Intro, ofstream, ifstream, and using what you know. Try to bear with me on this, remember this is the first time I'm explaining this to someone else...

Intro-
This section is built in a Question answer format...

What does fstream stand for?
fstream stands for File Stream.

Okay, I know what a file is, but what is a Stream?
A stream is a connection, Think of a stream a pipe. When you create a stream from your program to the file, it's like your connecting a pipe between them so they can send information. One difference is that a steam only runs one direction. If you open the stream to send information to the file, then you can't receive information through that stream you have to make another receiving stream.

What does ifstream and ofstream stand for and why use a weird name like that instead of open?
Well, I didn't create C++ so I don't know the exact reason that it was named like this instead of open or openf like in other languages, But my guess is to make the program more clear. Since were talking about sending information through streams, I'm guessing that he thought that it would be a nicer way to help people learn C++. ofstream stands for Output File Stream and istream stands for Input File Stream. That seems a lot more clear to me than just open or openf.

Now that I have answered these few questions for you, I believe that you should be a little more comfortable with File I/O in C++, If your not please let me know at CorruptBehavior@yahoo.com and I will try to make an update to this with more Q&A's to answer your questions. (but don't get carried away with the questions or suggestion..)

The first thing you should decide is wether or not you want to get data from or send data to the file. The first section, ofsteam, will describe how to send data to the file and the second section, ifstream, will describe how to get data from the file.

ofstream-
First thing to do is to create an output stream to the file. This is done like so...

ofstream OutputFile; // OutputFile is a variable name 
                     // representing the stream
Then we must define what file the stream should point to. This is done with the open() function like so...
OutputFile.open("filename.txt"); // This makes the stream 
                                 // point to the file
Now what if something goes wrong, your stream should be tested to check for errors, and if an error occurs then to shut down without a big mess. This is done with...
if( OutputFile.fail() ) { /* ERROR MESSAGE - End Program */ }
Okay now lets say it opens fine, now how would we write to the program? Easy, remember the cout syntax? All we have to do is use the same syntax with the stream variable name in place of cout...
OutputFile << endl << "This text goes to the file" << endl;
This wrote 'This text goes to the file' on a line by itself. So now your writing information to the file, what is left to do? Well everytime you open a stream you MUST close the stream.
This will cause serious memory leaks and other bad stuff the is equivalent to the Armageddon.. ;) So how do we do this? easy...
OutputFile.close();

That's it! So now we can send all the information we want to a file, What about getting that info back from the file? Well, continue on the next section...

ifstream
When creating an input steam we do basically the same thing as an output stream, but we are getting information FROM the file therefore the usage is a bit different...

ifstream InputFile;
InputFile.open("filename.txt");
if( InputFile.fail() ) { /* ERROR MESSAGE - End Program */ }
Okay, the file is open to be read from, now what? Well, do you recall the section on cout and cin? Do you remember how an ofstream uses the syntax of cout? Well, ifstream uses the syntax of cin...
InputFile >> DataFromFile; // DataFromFile is a variable just like in cin

So now we know how to get the information from the file. This is all there is to the basics now to go on into more advanced topics with some example codes.

Using What you Know
This section is once again example based. The reason I do so many example based sections is that I believe the best way to learn to code is through others examples. Call me old fashion but that is how I see it. The purpose of this section is to familiarize you with some of the file manipulation tool you have to work with in your C++ programming.

The hardest part of file manipulation is controlling where your CP, or current position is and editing depending on that position. I will try to put this as easily as possible.

Okay, lets say you open the file and your current CP is (0,0), or the first line first character, and you want to move to go to the 5th line and 4th character and change it to a 'r' you would do something like this:

#include <iostream.h>
#include <fstream.h>

int main()
{
    ifstream FIn;
    FIn.open('filename.ext');
        // open the file in read mode
    
    unsigned long i, j;
        // set variables to use as matrix counters

    char * file[2255][2255];
        // create matrix to hold all characters
        // in the file.

    for(i = 0; !(FIn.eof()); i++) // This loops through
    {                 // until it reaches the 
                      // end of the file.
                      // each time it increments
                      // this makes i be used to 
                      // count lines in the file.

      for(j = 0; !(FIn.eof()); j++) // This loops through
      {             // until it reaches the
                    // end of the file.
                    // each time it increments
                    // this makes j be used to
                    // count characters in each
                    // line.

        FIn >> file[i][j]; // This saves the character in the
                                 // matrix

      }
    }
    FIn.close(); // closes the input stream
    file[5][4] = "r"; 
        // replaces the character in the matrix
        // that represents the 4th character on the
        // 5th line with the "r" character.

    ofstream FOut;
    FOut.open('filename.ext');
        // the same file in write mode

    for(i = 0; file[i][j] != NULL; i++) // once again we are counting
    {                   // but this time we are counting
                        // through the matrix.
                        // remember we have created a
                        // virtual file with the matrix
                        // and we have to count through
                        // it replacing each character
                        // until we reach the end of the
                        // matrix which is represented
                        // by a NULL character, not an
                        // EOF.

      for(j = 0; file[i][j] != NULL; j++)
      {         // We are counting the virtual characters
                // in the matrix not the file

        FOut << file[i][j]; // we replace the character with the
                // virual character.
      }
    }
    FOut.close(); // we close the output stream
    cout << "Proccess Complete!" << endl;
    return 0;
}
Now this is just an example program and it demonstrates a few things one it demonstrates the usefulness of Matrices, it demonstrates how to work with basic file streams, and it demonstrates how when you don't know how to do something very well you can always find an alternative method. This is my method of editing parts of files with C++ because I work with large Databases a lot and it is easier to do it this way in a database environment than to use GET and PUT. I stand behind this because in databases you usually know what the structure and information is gonna be like. But for those of you that want to know how to use them here is get and put...
#include <iostream.h>
#include <fstream.h>

ifstream Fin;
ofstream Fout;
char tmporary;
int whtspc;

int main()
{
    Fin.open("ifilename.ext");
    Fout.open("ofilename.ext");

    while( !(Fin.eof()) )
    {
      Fin.get(tmporary);
      if(tmporary == "j") 
      {
        Fout.put("i");
      }
      else
      {
        Fout.put(tmporary);
      }
    }

    Fin.close();
    Fout.close();
    return 0;
}

This program takes all occurrences of i and replaces them with j then outputs this modified text to another file. Well that's all for File I/O, there are other things that you might want to know about this, remember "ONLY a Quick Guide!", so I suggest reading some peoples source codes to get some ideas.

Remember that there is usually more than one way to write things in C++ so always keep an open mind when reading someone's code.

Summary
In this section you learned how to read write and modify files.

< < < Lesson 8: Character Arrays | Lesson 10: Object Oriented Design > > >