Introduction to File Input/Output


Lecture 21


There are different operations that can be carried out on a file. These are-
1.    Creation of a new file
2.    Opening an existing file
3.    Reading from a file
4.    Writing to a file
5.    Moving to a specific location in a file (seeking)
6.    Closing a file

Let us now write a program to read a file and display its contents on the screen. We will first list the program and show what it does, and then dissect it line by line.

 
On execution of this program it displays the contents of the file ‘PR1.C’ on the screen. Let us now understand how it does the same.

Opening a File

Before we can read (or write) information from (to) a file on a disk we must open the file. To open the file we have called the function fopen( ). It would open a file “PR1.C” in ‘read’ mode, which tells the C compiler that we would be reading the contents of the file. Note that “r” is a string and not a character; hence the double quotes and not single quotes. In fact fopen( ) performs three important tasks when you open the file in “r” mode:

  1. Firstly it searches on the disk the file to be opened.
  2. Then it loads the file from the disk into a place in memory called buffer.
  3. It sets up a character pointer that points to the first character of the buffer.
Why do we need a buffer at all? Imagine how inefficient it would be to actually access the disk every time we want to read a character from it. Every time we read something from a disk, it takes some time for the disk drive to position the read/write head correctly. On a floppy disk system, the drive motor has to actually start rotating the disk from a standstill position every time the disk is accessed. If this were to be done for every character we read from the disk, it would take a long time to complete the reading operation. This is where a buffer comes in. It would be more sensible to read the contents of the file into the buffer while opening the file and then read the file character by character from the buffer rather than from the disk.
To be able to successfully read from a file information like mode of opening, size of file, place in the file from where the next read operation would be performed, etc. has to be maintained. Since all this information is inter-related, all of it is gathered together by fopen( ) in a structure called FILE. fopen( ) returns the address of this structure, which we have collected in the structure pointer called fp.
We have declared fp as
FILE *fp ;
The FILE structure has been defined in the header file “stdio.h” (standing for standard input/output header file). Therefore, it is necessary to #include this file.

Reading from a File

Once the file has been opened for reading using fopen( ), as we have seen, the file’s contents are brought into buffer (partly or wholly) and a pointer is set up that points to the first character in the buffer. This pointer is one of the elements of the structure to which pointer fp is pointing. To read the file’s contents from memory there exists a function called fgetc( ). This has been used in our program as,
ch = fgetc ( fp ) ;
fgetc( ) reads the character from the current pointer position, advances the pointer position so that it now points to the next character, and returns the character that is read, which we collected in the variable ch. Note that once the file has been opened, we no longer refer to the file by its name, but through the file pointer fp.
We have used the function fgetc( ) within an indefinite while loop. There has to be a way to break out of this while. When shall we break out... the moment we reach the end of file. But what is end of file? A special character, whose ASCII value is 26, signifies end of file. This character is inserted beyond the last character in the file, when it is created.
While reading from the file, when fgetc( ) encounters this special character, instead of returning the character that it has read, it returns the macro EOF. The EOF macro has been defined in the file “stdio.h”. In place of the function fgetc( ) we could have as well used the macro getc( ) with the same effect.
In our program we go on reading each character from the file till end of file is not met. As each character is read we display it on the screen. Once out of the loop,
we close the file.

Trouble in Opening a File

There is a possibility that when we try to open a file using the function fopen( ), the file may not be opened. While opening the file in “r” mode, this may happen because the file being opened may not be present on the disk at all. And you obviously cannot read a file that doesn’t exist. Similarly, while opening the file for writing, fopen( ) may fail due to a number of reasons, like, disk space may be insufficient to open a new file, or the disk may be write protected or the disk is damaged and so on.
Crux of the matter is that it is important for any program that accesses disk files to check whether a file has been opened successfully before trying to read or write to the file.
If the file opening fails due to any of the several reasons mentioned above, the fopen( ) function returns a value NULL (defined in “stdio.h” as #define NULL 0).
Here is how this can be handled in a program.
Closing the File
When we have finished reading from the file, we need to close it. This is done using the function fclose( ) through the statement,
fclose ( fp ) ;
Once we close the file we can no longer read from it using getc( ) unless we reopen the file. Note that to close the file we don’t use the filename but the file pointer fp. On closing the file the buffer associated with the file is removed from memory.
In this program we have opened the file for reading. Suppose we open a file with an intention to write characters into it. This time too a buffer would get associated with it. When we attempt to write characters into this file using fputc( ) the characters would get written to the buffer. When we close this file using fclose( ) three operations would be performed:
  1. The characters in the buffer would be written to the file on the disk.
  2. At the end of file a character with ASCII value 26 would get written.
  3. The buffer would be eliminated from memory.

You can imagine a possibility when the buffer may become full before we close the file. In such a case the buffer’s contents would be written to the disk the moment it becomes full.

Counting Characters, Tabs, Spaces

Having understood the first file I/O program in detail let us now try our hand at one more. Let us write a program that will read a file and count how many characters, spaces, tabs and newlines are present in it. Here is the program.



1 comments:

Unknown said...

This is great blog! Keep it up. chemical wash aircon price singapore

Post a Comment

Twitter Delicious Facebook Digg Stumbleupon Favorites More

 
Design by CelebrityDisk | Written by Alamin - link | Grants For Single Moms