0% found this document useful (0 votes)
16 views

File Handling in C

Uploaded by

bojodis702
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views

File Handling in C

Uploaded by

bojodis702
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

File Handling in C

Memory is volatile and its contents would be lost once the program is terminated. So if we need the
same data again, it would have to be either entered through the keyboard again or would have to be
regenerated programmatically. Obviously both these operations would be time consuming. At such
times it becomes necessary to store the data in a manner that can be later retrieved and displayed
either in part or in whole. This medium is usually a ‘file’ on the disk. All data stored on the disk is in
binary form. How this binary data is stored on the disk varies from one OS to another. However, this
does not affect the C programmer since he has to use only the library functions written for the particular
OS to be able to perform input/output. It is the compiler vendor’s responsibility to correctly implement
these library functions by taking the help of OS.

Our program C library function O.S Disk

File Operations
There are different operations that can be carried out on a file. These are:
➢ Creation of a new file
➢ Opening an existing file
➢ Reading from a file
➢ Writing to a file
➢ Moving to a specific location in a file (seeking)
➢ Closing a file

Now go through the following program before the discussion of file operation modes. The program will
read a file and display its contents on the screen.

# include "stdio.h"
main( )
{
FILE *fp ;
char ch ;
clrscr();
fp = fopen ( "text.txt", "r" ) ;
while ( 1 )
{
ch = fgetc ( fp ) ;
if ( ch == EOF )
break ;
printf ( "%c", ch ) ;
}
fclose ( fp ) ;
getch();
}
On execution of the above program it displays the contents of the file ‘text.txt’ on the screen. Suppose
you have a stored file in your laptop under C drive named text.txt (path: c:\text.txt).The content in the
file is “I love my India”. Then output of the above program will be “I love my India”, which will be
displayed on the screen.

File Opening Modes


In the above program we have opened the file in read (“r”) mode. However, “r” is but one of the several
modes in which we can open a file. Following is a list of all possible modes in which a file can be opened.
The tasks performed by fopen( ) when a file is opened in each of these modes are also mentioned.

"r" Searches file. If the file is opened successfully fopen( ) loads it into memory and sets up a pointer
which points to the first character in it. If the file cannot be opened fopen( )returns NULL. Operations
possible – reading from the file.

"w" Searches file. If the file exists, its contents are overwritten.If the file doesn’t exist, a new file is
created. Returns NULL, if unable to open file. Operations possible – writing to the file.

"a" Searches file. If the file is opened successfully fopen( ) loads it into memory and sets up a pointer
that points to the last character in it. If the file doesn’t exist, a new file is created. Returns NULL, if
unable to open file. Operations possible - adding new contents at the end of file.

"r+" Searches file. If is opened successfully fopen( ) loads it into memory and sets up a pointer which
points to the first character in it. Returns NULL, if unable to open the file. Operations possible - reading
existing contents, writing new contents, modifying existing contents of the file.

"w+" Searches file. If the file exists, its contents are overwritten. If the file doesn’t exist a new file is
created. Returns NULL, if unable to open file. Operations possible - writing new contents, reading them
back and modifying existing contents of the file.

"a+" Searches file. If the file is opened successfully fopen( ) loads it into memory and sets up a pointer
which points to the first character in it. If the file doesn’t exist, a new file is created. Returns NULL, if
unable to open file. Operations possible - reading existing contents, appending new contents to end of
file. Cannot modify existing contents.

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 “text.txt” 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:
➢ Firstly it searches on the disk the file to be opened.
➢ Then it loads the file from the disk into a place in memory called buffer.
➢ It sets up a character pointer that point 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.

Same argument also applies to writing information in a file. Instead of writing characters in the
file on the disk one character at a time it would be more efficient to write characters in a buffer and
then finally transfer the contents from the buffer to 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.

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. So,
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...

#include "stdio.h"
main( )
{
FILE *fp ;
fp = fopen ( "PR1.C", "r" ) ;
if ( fp == NULL )
{
puts ( "cannot open file" ) ;
exit( ) ;
}
}

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 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.

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:

➢ The characters in the buffer would be written to the file on the disk.
➢ At the end of file a character with ASCII value 26 would get written.
➢ The buffer would be eliminated from memory.

*Count chars, spaces, tabs and newlines in a file

# include "stdio.h"
Void main( )
{
FILE *fp ;
char ch ;
int nol = 0, not = 0, nob = 0, noc = 0 ;
fp = fopen ( "PR1.C", "r" ) ;
while ( 1 )
{
ch = fgetc ( fp ) ;
if ( ch == EOF )
break ;
noc++ ;
if ( ch == ' ' )
nob++ ;
if ( ch == '\n' )
nol++ ;
if ( ch == '\t' )
not++ ;
}
fclose ( fp ) ;
printf ( "\nNumber of characters = %d", noc ) ;
printf ( "\nNumber of blanks = %d", nob ) ;
printf ( "\nNumber of tabs = %d", not ) ;
printf ( "\nNumber of lines = %d", nol ) ;
}

A File-copy Program
We have already used the function fgetc( ) which reads characters from a file. Its counterpart is a
function called fputc( ) which writes characters to a file. As a practical use of these character I/O
functions we can copy the contents of one file into another, as demonstrated in the following program.
This program takes the contents of a file and copies them into another file, character by character.

#include "stdio.h"
main( )
{
FILE *fs, *ft ;
char ch ;
fs = fopen ( "pr1.c", "r" ) ;
if ( fs == NULL )
{
puts ( "Cannot open source file" ) ;
exit( ) ;
}
ft = fopen ( "pr2.c", "w" ) ;
if ( ft == NULL )
{
puts ( "Cannot open target file" ) ;
fclose ( fs ) ;
exit( ) ;
}
while ( 1 )
{
ch = fgetc ( fs ) ;
if ( ch == EOF )
break ;
else
fputc ( ch, ft ) ;
}
fclose ( fs ) ;
fclose ( ft ) ;
}
I hope most of the stuff in the program can be easily understood, since it has already been dealt with in
the earlier section. What is new is only the function fputc( ). Let us see how it works.
Writing to a File
The fputc( ) function is similar to the putch( ) function, in the sense that both output characters.
However, putch( ) function always writes to the VDU, whereas, fputc( ) writes to the file.
Which file? The file signified by ft in the the above program . The writing process continues till all
characters from the source file have been written to the target file, following which the while loop
terminates. Note that our sample file-copy program is capable of copying only text files. To copy files
with extension .EXE or .COM, we need to open the files in binary mode.

String (line) I/O in Files


For many purposes, character I/O is just what is needed. However, in some situations the usage of
functions that read or write entire strings might turn out to be more efficient. Reading or writing strings
of characters from and to files is as easy as reading and writing individual characters. Here is a program
that writes strings to a file using the function fputs( ).

Below is a sample program in which we will receive strings from keyboard and write them to a file
#include "stdio.h"
main( )
{
FILE *fp ;
char s[80] ;
fp = fopen ( "POEM.TXT", "w" ) ;
if ( fp == NULL )
{
puts ( "Cannot open file" ) ;
exit( ) ;
}
printf ( "\nEnter a few lines of text:\n" ) ;
while ( strlen ( gets ( s ) ) > 0 )
{
fputs ( s, fp ) ;
fputs ( "\n", fp ) ;
}
fclose ( fp ) ;
}

And here is a sample run of the program...


Enter a few lines of text:
Shining and bright, they are forever,
so true about diamonds,
more so of memories,
especially yours !

Note that each string is terminated by hitting enter. To terminate the execution of the program, hit
enter at the beginning of a line. This creates a string of zero length, which the program recognizes as the
signal to close the file and exit. We have set up a character array to receive the string; the fputs( )
function then writes the contents of the array to the disk. Since fputs( ) does not automatically add a
newline character to the end of the string, we must do this explicitly to make it easier to read the string
back from the file.

Here is a program that reads strings from a disk file.


#include "stdio.h"
main( )
{
FILE *fp ;
char s[80] ;
fp = fopen ( "POEM.TXT", "r" ) ;
if ( fp == NULL )
{
puts ( "Cannot open file" ) ;
exit( ) ;
}
while ( fgets ( s, 79, fp ) != NULL )
printf ( "%s" , s ) ;
fclose ( fp ) ;
}
And here is the output...
Shining and bright, they are forever,
so true about diamonds,
more so of memories,
especially yours !

The function fgets( ) takes three arguments. The first is the address where the string is stored, and the
second is the maximum length of the string. This argument prevents fgets( ) from reading in too
long a string and overflowing the array. The third argument, as usual, is the pointer to the structure FILE.
When all the lines from the file have been read, we attempt to read one more line, in which case fgets( )
returns a NULL.

You might also like