File Handling

Download as pdf or txt
Download as pdf or txt
You are on page 1of 45

Introduction to File Handling

by
Dr. Subodh Srivastava
CSE,IIT (BHU)

WHAT IS A FILE ?
Wherever there is a need to handle large
volumes of data, it is advantageous to store data
on the disks and read whenever necessary.
This methods employs the concept of files to
store data.
A file is a place on disk where a group of related
data is stored.

C supports a number of functions that have the ability to perform


basic file operations, which include:
naming a file
opening a file
reading data from a file
writing data to a file
closing a file
There are two distinct ways to perform file operation in C.

1. Low level I/0 Operation (It uses operating


system calls)
2. High level I/O Operation (It uses function in
Cs Standard I/0 library )

Defining and Opening a File. Before storing data in a file in the


secondary memory , certain things about the file must be
specified to the operating system. These include:
Filename
Data Structure
Purpose

Filename. It is a string of characters that makes up a valid


filename for an operating system.
It may contain two parts, a primary name an optional period
with an extension.
e.g.: Input.dat
Store
PROG.C
Student.C

Data Structure. Data structure of a file is


defined as File in the library of standard I/O
function definitions.
All files should be declared as of type FILE
before they are used.
Purpose. when we open a file , we must specify
what we want to do with the file.
Following is the general format for declaring
and opening a file.
File *fp;
fp = fopen( filename, mode);

The first statement declares the variable fp as a


pointer to the data type FILE.
The second statement opens the file named
and assigns an identifier to the FILE type
pointer fp.
This pointer which contains all the information about the file
is subsequently used as a communication link between the
system and the program.
The second statement also specifies the purpose of opening
this file. The mode does this job.
Mode can be one of the following:
r
Opens the file for reading only
w
Opens the file for writing only.

a
Open the file for appending (or adding) data to it.

Depending on the mode are specified as string.


They should be enclosed in double quotation
marks.
Other additional modes of operation are:
r+ The existing file is opened from the
beginning for both reading and writing.
W+ Same as w except both for reading and
writing.
a+ Same as a except both for reading and
writing.

#include<stdio.h> /* must be included for high level file I/ */


main()
{

FILE *fptr;

fptr=fopen(Text.DAT, w);

if(!fptr)

prinf(\nCant open file for writing\n);

else

..

..

fclose(fptr);

}
Once a file is opened it has own FILE structure having information about
the file being used, such as its current size, its location in computer
memory, etc. It has a character pointer that points to the character to be read
or written.

Here, the pointer fptr will point to a structure of type FILE,


indicating the beginning to the data file buffer area. As
mentioned earlier FILE is defined in stdio.h header file.
The fopen() function opens the data file TEXT.DAT as a write
only file(if possible)
And returns the pointer to the beginning of the buffer area and
assigns it to the pointer variable fptr.
An error message will be displayed if the file TEXT.DAT
cannot be opened (i.e., NULL is returned,NULL is a macro
defined in stdio.h):
if(!fptr) or if(fptr==NULL)
We can also combine the fopen and if statement, as given below
: if((fptr =fopen (TEXT.DAT, w))==NULL)
After successfully opening the file, the file processing statement
will be performed using the pointer variable fptr, rather than by
using the file i.e, TEXT.DAT.

The file is closed using the pointer variable fptr,


rather than the filename i.e.,TEXT.DAT(in case
it was opened for use).

The important file handling high level I/0


functions that are available in C language
library are:

Function Name

Operation

fopen()

Creates a new file for use or open an existing file


for use

fclose()

Close a file which has been opened for use.

getc()

Reads a character from a file

putc ()

Writes a character to a file

fprintf ()

Writes a set of data values from a file

fscanf()

Reads a set of data values from a file

getw()

Reads an integer from a file

putw()

Writes an integer to a file.

/* checking the successful opening when we open a file for reading*/


#include<stdio.h> /* must be included for high level file I/ */
main()
{

FILE *fptr;

fptr=fopen(Text.DAT, r); /*open file for reading */

if(!fptr)

prinf(\nCant open file for reading\n);

exist();

....

....

Input / Output Operations on Files:


A data file must be created before processing it.
/* create a file to store text and display the contents*/
#include<stdio.h>
main()
{
FILES *fptr;
char ch;
fptr=fopen (TEXT.DAT, w); /*open file to output data */
clrscr();
if (!fptr)
printf(\nCant open file for writing\n);
else
{
printf(Enter the text :\n);
printf(\nPress <ctrl+z> (DOS));
printf( 0r <ctrl+d> (UNIX) for termination\n\n);

while((ch=getchar()) !=EOF)
{
putc(ch,fptr);
fclose(fptr);
fptr=fopen(TEXT.DAT, r); /*open file to input data*/
if(!fptr)
printf(\nCant open file for reading\n);
else
{
printf(\nThe text stored in the file is :\n\n);
while( (ch=getc(fptr)) ! EOF)
{
printf(c,ch);
}
fclose(fptr);
}
}

The output of program will be:


Enter the text:
Press<ctrl+z>(DOS) or <ctrl+|d>(UNIX) for termination
Programming in C is a fun!
Have faith in yourself;
You may be a successful programmer.
^z
The text stored in the file is:
Programming in C is fun!
Have faith in yourself.
You may be a successful programmer.
In the above program the statement
putc(ch,fptr);
Writes the character stored in the character variable ch to the file associated
with FILE pointer fptr(i.e., file TEXT.DAT).
The file pointer fptr moves one character position for each operation of
putc.The end of data is marked by entering an EOF character.

(i.e.,<ctrl+z) on DOS or <ctrl+d> on UNIX).

The fil e name is again represented for reading. The file contents are read
character by character and displayed on the screen using statement.
ch=getc(fptr)

Inside the while loop i.e while(ch=getc(fptr)) !=EOF)

When getc () encounters the end-of-file mark i.e, EOF, the reading from the
ends. If end of file condition is not tested then either an infinite loop may start
or program may terminate abonormally.

Note: getc() and putc() are macros,whereas fgetc() and fputs are their
function versions.

/* read a text file and create another file in which multiple blanks are replaced
by a single one */
#include<stdio.h>
main()
{
FILE *fptr1, *fptr2;
char source[13],target [13];

char ch;
int flag=1;
clrscr();
printf(Enter source file name to be copied\n\n);
gets(source);

fptr1=fopen(source, r); /*open file in input mode */

if (! fptr1)

printf(\nCant open source file for reading\n);

else

printf(\nEnter target file name to transfer source file\n\n);


gets(target);
fptr2=fopen(target, w); /*open file in output mode */
if(!fptr2)
printf(\nCant open target file for writing\n);
else

while(flag)

ch=fgetc(fptr1);

if(ch==EOF)

breaks;

fputc(ch,fptr2);

if (ch == )


while (ch = = )

ch=fgetc(fptr1);

if( ch = = EOF)

flag=0;

fputc (ch,fptr2);

printf(\n Source file has been copied to target file\n);

printf(\nMultiple blanks have been changed to single one\n);

fclose(fptr2); /* close file*/


}
}

In C we use FILE * to represent a pointer to a file.


fopen is used to open a file. It returns the special
value NULL to indicate that it couldn't open the file.
FILE *fptr;
char filename[]= "file2.dat";
fptr= fopen (filename,"w");
if (fptr == NULL) {
fprintf (stderr,
ERROR);
/* DO SOMETHING */
}

Modes for opening files


The second argument of fopen is the mode in
which we open the file. There are three
"r" opens a file for reading
"w" opens a file for writing - and writes over all
previous contents (deletes the file so be careful!)
"a" opens a file for appending - writing on the
end of the file

The exit() function


Sometimes error checking means we want
an "emergency exit" from a program. We
want it to stop dead.
In main we can use "return" to stop.
In functions we can use exit to do this.
Exit is part of the stdlib.h library
exit(-1);
in a function is exactly the same as
return -1;
in the main routine

Writing to a file using fprintf


fprintf works just like printf and sprintf except
that its first argument is a file pointer.
FILE *fptr;
fptr= fopen ("file.dat","w");
/* Check it's open */
fprintf (fptr,"Hello World!\n");

We could also read numbers from a file using


fscanf but there is a better way.

Reading from a file using fgets


fgets is a better way to read from a file
We can read into a string using fgets
FILE *fptr;
char line [1000];
/* Open file and check it is open */
while (fgets(line,1000,fptr) != NULL) {
printf ("Read line %s\n",line);
}

fgets takes 3 arguments, a string, a maximum


number of characters to read and a file pointer.
It returns NULL if there is an error (such as EOF)

Closing a file
We can close a file simply using fclose and the
file pointer. Here's a complete "hello files".
FILE *fptr;
char filename[]= "myfile.dat";
fptr= fopen (filename,"w");
if (fptr == NULL) {
printf ("Cannot open file to write!\n");
exit(-1);
}
fprintf (fptr,"Hello World of filing!\n");
fclose (fptr);

Great Muck-Ups in C #72 of 100


We use the file pointer to close the file - not the
name of the file
FILE *fptr;
fptr= fopen ("myfile.dat","r");
/* Read from file */
fclose ("myfile.dat");
/* Ooops - that's wrong */

Three special streams


Three special file streams are defined in the
stdio.h header
stdin reads input from the keyboard
stdout send output to the screen
stderr prints errors to an error device
(usually also the screen)
What might this do:
fprintf (stdout,"Hello World!\n");

Reading loops
It is quite common to want to read every
line in a program. The best way to do this
is a while loop using fgets.
/* define MAXLEN at start using enum */
FILE *fptr;
char tline[MAXLEN]; /* A line of text */
fptr= fopen ("sillyfile.txt","r");
/* check it's open */
while (fgets (tline, MAXLEN, fptr) != NULL) {
printf ("%s",tline); // Print it
}
fclose (fptr);

Using fgets to read from the


keyboard

fgets and stdin can be combined to get a


safe way to get a line of input from the user
#include <stdio.h>
int main()
{
const int MAXLEN=1000;
char readline[MAXLEN];
fgets (readline,MAXLEN,stdin);
printf ("You typed %s",readline);
return 0;
}

Getting numbers from strings


Once we've got a string with a number in it
(either from a file or from the user typing)
we can use atoi or atof to convert it to a
number
The functions are part of stdlib.h
char numberstring[]= "3.14";
int i;
double pi;
pi= atof (numberstring);
i= atoi ("12");

Both of these functions return 0 if they have a problem

Great Muck-Ups in C #11 of 100


fgets includes the '\n' on the end
This can be a problem - for example if in
the last example we got input from the user
and tried to use it to write a file:
FILE *fptr;
char readfname[1000];
fgets (readfname,1000,stdin);
fptr= fopen (readfname,"w");
/* oopsie - file name also has \n */

Even experienced programmers can make


this error

fscanf.c
#include <stdio.h>
#include <stdlib.h>
int main ( )
{
double x ;
FILE *ifp ;

/* for exit */

/* try to open the file for reading, check if successful */


/* if it wasn't opened exit gracefully */
ifp = fopen("test_data.dat", "r") ;
if (ifp == NULL) {
printf ("Error opening test_data.dat\n");
exit (-1);
}
fscanf(ifp, "%lf", &x) ;
/* read one double from the file */
fclose(ifp);
/* close the file when finished */

/* check to see what you read */


printf("x = %.2f\n", x) ;
return 0;
}

Detecting end-of-file
with fscanf
When reading an unknown number of data
elements from a file using fscanf( ), we
need a way to determine when the file has no
more data to read, i.e, we have reached the end
of file.
Fortunately, the return value from fscanf( )
holds the key. fscanf( ) returns an integer
which is the number of data elements read from
the file. If end-of-file is detected the integer
return value is the special value EOF

Structures in C
In C, we can create our own data types - FILE is
an example of this.
If programmers do a good job of this, the end user
doesn't even have to know what is in the data type.
struct is used to describe a new data type.
typedef is used to associate a name with it.
int, double and char are types of variables.
With struct you can create your own. It is a
new way to extend the C programming language.

The struct statement


Here is an example struct statement.
#include <stdio.h>
struct line {
int x1, y1; /* co-ords of 1 end of line*/
int x2, y2; /* co-ords of other end */
};
main()
{
struct line line1;
.
This defines the variable line1 to be
.
a variable of type line
}

Typedef
Typedef allows us to associate a name with
a structure (or other data type).
Put typedef at the start of your program.
typedef struct line {
int x1, y1;
int x2, y2;
} LINE;
int main()
{
LINE line1;
}

line1 is now a structure of line type


This is what was happening with all
that FILE * stuff

Accessing parts of a struct


To access part of a structure we use the dot
notation
LINE line1;
line1.x1= 3;
line1.y1= 5;
line1.x2= 7;
if (line1.y2 == 3) {
printf ("Y co-ord of end is 3\n");
}

What else can we do with


structs?
We can pass and return structs from
functions. (But make sure the function
prototype is _AFTER_ the struct is
declared)
typedef struct line {
int x1,y1;
int x2,y2;
} LINE;
LINE find_perp_line (LINE);
/* Function takes a line and returns a
perpendicular line */

What's the point of all this with


structs?
It makes your programming easier and it makes
it easier for other programmers.
FILE * was a typedef'd struct but you could use
it without knowing what was inside it.
You can extend the language - for example, if
you use complex numbers a lot then you can
write functions which deal with complex nos.

Complex
no
functions
typedef struct complex {
float imag;
float real;
} CPLX;
CPLX mult_complex (CPLX, CPLX);
int main()
{
/* Main goes here */
}
CPLX mult_complex (CPLX no1, CPLX no2)
{
CPLX answer;
answer.real= no1.real*no2.real - no1.imag*no2.imag;
answer.imag= no1.imag*no2.real + no1.real*no2.imag;
return answer;
}

Dynamic memory allocation


How would we code the "sieve of Eratosthenes"
to print all primes between 1 and n where the
user chooses n?
We _could_ simply define a HUGE array of
chars for the sieve - but this is wasteful and how
big should HUGE be?
The key is to have a variable size array.
In C we do this with DYNAMIC MEMORY
ALLOCATION

A dynamically allocated sieve


#include <stdlib.h>
void vary_sieve (int);
void vary_sieve (int n)
/* Sieve to find all primes from 1 - n */
{
char *sieve;
int i;
sieve= (char *)malloc (n*sizeof(char));
/* check memory here */
for (i= 0; i < n; i++)
sieve[i]= UNCROSSED;
/* Rest of sieve code */
free (sieve); /* free memory */
}

A closer look at malloc


Let's look at that malloc statement again:
sieve= (char *)malloc(n*sizeof(char));

This is a CAST
sizeof(char) returns how
we want
(remember them)
much memory a char
n chars
that forces the variable
takes
to the right type (not
needed)
This says in effect "grab me enough memory for 'n' chars"

Free
The free statement says to the computer "you
may have the memory back again"

free(sieve);

essentially, this tells the machine that the memory we


grabbed for sieve is no longer needed and can be used
for other things again. It is _VITAL_ to remember to
free every bit of memory you malloc

Check the memory from malloc


Like fopen, malloc returns NULL if it has a
problem
Like fopen, we should always check if malloc
manages to get the memory.
float *farray;
/* Try to allocate memory for 1000 floats */
farray= malloc(1000*sizeof(float));
if (farray == NULL) {
fprintf (stderr, "Out of memory!\n");
exit (-1);
}

You might also like