article

Intro to C/C++ Part 10: File I/O (part 1)

Email
Submitted on: 1/1/2015 7:43:00 AM
By: Alexander of CProgramming.com (from psc cd)  
Level: Intermediate
User Rating: By 15 Users
Compatibility: C++ (general)
Views: 1652
 
     This is a slightly more advanced topic than what I have covered so far, but I think that it is useful, and I think it will be useful to many people. File i/o is basically reading, and writing files. This lesson will only cover text files, that is, files that are readable through a text editor, as opposed to binary files(exes for example). It will not cover a great deal, for example, this lesson will not deal with searching files or reading specific data from files. It will merely be concerned with opening, writing, and reading text files. Don't worry though, lesson 11 will cover much more on this topic.

 
				

 

     Well, how does it all start anyway? Files have their own specific functions to use, as well as their own data-type, called a FILE(There is more to this, but right not it is not important, and it will be explained later, when it is useful). The way to use the FILE type is the same way as using an integer, or a float, or a char:

FILE *newfile; //Creates a FILE called newfile(don't forget that it is a pointer)

Now, we can't use this unless there is a way to give the FILE(*newfile) a file to point to.   The way this works is that it is what is called a stream. That means that it is where the output will go to. To direct *newfile to a file the command to use is
FILE *fopen(const char *filename, const char *mode), found in stdio.h. It simply returns a pointer to a FILE, but it is easy enough to use. For example:

FILE *newfile: //Creates a FILE called newfile

newfile=fopen("c:\AUTOEXEC.BAT", "r");//open up for reading your autoexec.bat file, and assign

//it to newfile

     Basically, fopen accepts two strings. One of them is the file name, including the path, and the other is what the file will be used for(the mode). In this case, the r designates the file will only be opened for reading. Therefore, the file cannot be modified while it is open. That is probably a good idea, because editing your autoexec.bat file with giberish is not a good idea!


     For a reference here is a chart listing the different ways you open a file:

r Open for reading only.
w Creates a file for writing. If a file by that name already exists, it will be overwritten.
a Append; open for writing at the end of the file, or create the file if it does not exist.
r+ Open an existing file for reading and writing.
w+ Create a new file for reading and writing. If a file by that name already exists, it will be overwritten.
a+ Open for append; open (or create if the file does not exist) for update at the end of the file.

     Keep in mind that each of these has a different use, and that you should choose the one most appropriate for you task. For now however, lets concentrate on reading a file.

     Now, let's say you want to print the contents of autoexec.bat to your screen. Assuming you want to make a program to do this you would need a function for reading from a file. There are numerous useful ones, but for now we will use int fgetc(FILE *stream)(Note that it returns an int, but the range will still be printable(so it is the same as a char), defined in iostream.h. Basically, fgetc will get the next character from a file you give it(that is, the stream you give it). An example would be the following code to display the first few characters of your autoexec.bat file:

 

#include <iostream.h> //For cout
#include <stdio.h> //For all file i/o functions
void main()
{
int count=0; //Just a variable to keep from reading the file forever.
FILE *afile; //We need a FILE to point to the stream to allow access to the fil
afile=fopen("c:/AUTOEXEC.BAT", "r"); //Open up the autoexec.bat file for reading

//No, I do not know why it must be a forward slash.
while(count<10)
{
cout<<(char)fgetc(afile); //Notice that fgetc returns an int, which can be printed.

//Please note the use of (char) to 'typecast' the returned integer. That means that it makes
//it into a printable character from the number. There is more on this in lesson 11, which
//I suggest you read.(Note that chars basically convert their ASCII numbers into the
//appropriate printable characters. 65= 'A' for example.

count++; //I don't think it should read forever, right?

}

fclose(afile); //A surprise(don't worry, just use it to close a file when done).

//Just put in the pointer to the stream(the FILE thingy)

}

     This program is fairly simple, and it does not take advantage of many of C's more useful file operations. Note though, that it is going to print out only a few characters. What if you wanted to print the entire file out, though? Well, that is where a thing called the EOF(end-of-file) comes into play. It is essentially a null that will signal the end of the file has been reached.

     So, how would you make a program to use this? Well, fgetc retrieves a character from the file, and it will return the EOF when it reaches the end of the file. Now, it is possible to use a loop that will check to see if the last character is equal to the EOF. For example, CHARACTERREAD!= EOF. This would return true if the CHARACTERREAD is not the EOF.

Here's how I would do it:

#include <iostream.h> //For cout

#include <stdio.h> //For all file i/o functions

void main()

{

FILE *afile; //We need to define a FILE type to open a file
afile=fopen("c:/AUTOEXEC.BAT", "r"); //Opens autoexec.bat, only to read, not write it. afile
//is now the stream pointing to the file autoexec.bat,
//and is used to do operations with autoexec.bat
char c; //Without a character to store the information the program won't work
while(c!=EOF) //Checking to see if the character just read is the end of the file

{
c=fgetc(afile); //This reads in the character
//Note that it is not necessary to typecast the fgetc return, as it is automatically turned
//into a printable character when char c is a character.

cout<<c; //The prints out the character(as you SHOULD know!)

}

fclose(afile); //Just to be safe, close the file!

}

     Ok, so you finally got it to print out! Well, what is the next thing to do? Why not have a program to make a backup of autoexec.bat? There is a new function that you will need to add to your repetoire before this can be done. The new function is fputc, defined in stdio.h. int futc(int c, FILE *filethinghere);. Basically, it will return the character given to it, or it will return an EOF. It accepts a character as the first argument, and a pointer to a stream(the FILE thing) as the second argument. Here is an example of how to use it:

fputc('A', newfile); //Writes the character 'A' to the file pointed to by newfile

     However, don't forget that this does not always work. The file the stream points to has to have been opened for writing, not just reading. Usually you will want to append to a file, but in the case of our next example we want to create a new file, and overwrite an old one.

     Now that we have a function to print to a file, why not finish up with one program to backup autoexec.bat. Basically, we will use the same loop as in the first function, that is, checking to see if the end of the file is reached, otherwise it will continue to print out characters. This time however, it will not print the characters to the screen. Instead, it will print the characters to another file(In the example, backup.aut).

-----------------------------------------------------------------------------------------------

WARNING: If you currently have a file called backup.aut you will have it overwritten! DO NOT run the example program if you have the file backup.aut in the directory with your compiler! Otherwise, you will hae it overwritten.

-----------------------------------------------------------------------------------------------

#include <stdio.h> //Needed for file i/o functions(including fopen!)

void main()

{

FILE *autoexec, *backup; //There are two files this time, the AUTOEXEC.BAT and the backup

// file

autoexec=fopen("c:\AUTOEXEC.BAT", "r");//Open autoexec.bat to read the file

backup=fopen("backup.aut", "w"); //Create(or overwrite)backup.aut for writing

char c; //We need a buffer for reading in the charactesr

while(c!=EOF) //Just checking to see if it's the end of the file

{

c=fgetc(autoexec); //Reading in a character from autoexec.bat

fputc(c, backup); //Writing a character to the backup file!

}

fclose(autoexec);

fclose(backup); //Closing the files to finish it all up!

}

Wow! It's a program that could be useful. Feel free to use it anytime you like. Just remember how it works. Don't think this is the end of the file i/o information. There is more, but for now this should be enough to whet your appetite. Oh, and you case use fputc to write user input to a file also! I think you can figure it out!


Other 10 submission(s) by this author

 


Report Bad Submission
Use this form to tell us if this entry should be deleted (i.e contains no code, is a virus, etc.).
This submission should be removed because:

Your Vote

What do you think of this article (in the Intermediate category)?
(The article with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor (See voting log ...)
 

Other User Comments


 There are no comments on this submission.
 

Add Your Feedback
Your feedback will be posted below and an email sent to the author. Please remember that the author was kind enough to share this with you, so any criticisms must be stated politely, or they will be deleted. (For feedback not related to this particular article, please click here instead.)
 

To post feedback, first please login.