File Handling
The essential things of computing are saving
and retrieving the data. Everyone who uses the computer needs to save and
retrieve lot many things. The key to saving and retrieving the information
using computer is files.
Information stored in the device in the form
of a data file. File allows us to store information permanently, and to access
and alter information whenever necessary.
There are two different types of file
- Stream
oriented data files – These file also called as standard files.
- System
oriented data files – These files also called as low level files.
Stream oriented files can be divided into two
categories
§ In the first
category, data files comprising consecutive characters. These characters can be
interpreted as individual data items.
§ The second category
of stream oriented data files, often referred to as unformatted data files,
organizes data into blocks containing contiguous bytes of information.
File I/O operations in C are carried out by
library functions.
The different operations that can be carried
out on a file are as follows
§ Creation of new file.
§ Opening new file.
§ Reading from file.
§ Writing to a file.
§ Going through the
file contents.
§ Closing a file.
Terms and conditions
§ Always include file
stdio.h.
§ Declare file pointer
by using type FILE.
§ After declaration
file pointer should be initialize by file open function.
§ After performing
single operation always close file.
How to declare file pointer
Initialization
filepointer = fopen(“filename”,”mode”);
|
Different modes of file
a
|
Appending mode
|
a+
|
Appending and reading
|
r
|
Read only
|
r+
|
Reading and writing
|
w
|
Write only
|
w+
|
Writing and reading
|
Functions for reading from a file
getc()
|
Reads a character from a file that has been
opened in read mode.
|
fgets()
|
Reads a string from file.
|
getw()
|
Reads an integer from a file.
|
fscanf()
|
Reads formatted input from a file.
|
Functions for writing to a file
putc()
|
Writes a character to a file that has been
opened in write or append mode.
|
fputs()
|
Writes a string to a file.
|
putw()
|
Writes an integer to a file.
|
fprintf()
|
Writes formatted output to a file.
|
Files
and Binary I/O
All above functions only work with text
files. But if we want to handle binary files then we have to use different set
of functions.
Text
files
A text file is a generic description of a
computer file. The information is represented in terms of character set. These files are in human readable forms.
// prog to write a single character to file
#include<stdio.h>
#include<conio.h>
void main()
{
FILE
*fp; //Declaration
of file pointer
char
ch;
clrscr();
fp=fopen("c:\\abc.txt","w"); //File open in write mode
printf("Enter any character to store in file \n");
flushall();
scanf("%c",&ch); //scan character
from user
putc(ch,fp); // store in file
fclose(fp);
printf("\nFile created successfully...");
getch();
}
Output:
Enter any character to store in
file
$
File created successfully...
// prog to read single character from file
#include<stdio.h>
#include<conio.h>
void main()
{
FILE
*fp;
char
ch';
clrscr();
//open file in read mode
fp=fopen("c:\\abc.txt","r"); //File open in read
mode
printf("\nCharacter from file: ");
ch=getc(fp); //Reads single character from file
printf("%c",ch);
fclose(fp);
getch();
}
Output:
Character from file: $
In following program two operations are
merged. Here you should enter single character but you can be entering one by
one character as well as you can read one by one character from a single file.
How it is possible? Look at following program.
// prog to write & read a single
character from file
#include<stdio.h>
#include<conio.h>
void main()
{
FILE
*fp;
char
ch,ans='y'; //’y’
value stored in variable ans because initially while loop must be true.
clrscr();
fp=fopen("c:\\abc.txt","w");
while(ans=='y')
{
printf("Enter any character to store
in file \n");
flushall(); //this function is use to clean buffer (temporarily memory
storage)
scanf("%c",&ch);
putc(ch,fp); //
store in file
printf("Do
you want to enter more character?\n");
flushall();
scanf("%c",&ans); //Ask user to store
more character to file if ‘y’ is entered then only loop get reapeate
}
fclose(fp);
fp=fopen("c:\\abc.txt","r"); //open file in read mode
printf("character from file....\n");
while((ch=getc(fp))!=EOF) //Read single
character at a time till end of file
{
printf("%c",ch);
}
fclose(fp);
getch();
}
Output:
Enter any character to store in
file
M
Do you want to enter more
character?
y
Enter any character to store in
file
u
Do you want to enter more
character?
y
Enter any character to store in
file
m
Do you want to enter more
character?
y
Enter any character to store in
file
b
Do you want to enter more
character?
y
Enter any character to store in
file
a
Do you want to enter more character?
y
Enter any character to store in
file
i
Do you want to enter more
character?
n
character from file....
Mumbai
In following example instead of fixed path
filename variable is used. In this case file compulsory created in TCC folder.
//copy contents of source file into target
file
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
void main()
{
FILE
*fp,*fc;
char
sfname[12],tfname[12],ch; //source and target files name are declared
clrscr();
printf("Enter source filename\n");
gets(sfname);
printf("Enter target filename\n");
gets(tfname);
fp=fopen(sfname,"r"); //Open
source file in read mode
if(fp
== NULL) //If fp returns NULL then file not exists
{
printf("File does not exists...\n");
getch();
exit(0); //After showing above statement program will close.
}
else
{
fc =
fopen(tfname,"w"); //Open target file in write only mode
while((ch=getc(fp))!=EOF)
{
putc(ch,fc); //fp reads character from source file and fc writes
character to target file till end of source file
}
printf("File is copied successfully...\n");
}
fcloseall();
//close both files
fc=fopen(tfname,"r"); //To check whether
copied done successfully or not, open target file in read mode
printf("Copied contents of file...\n");
while((ch=getc(fc))!=EOF) //Read characters
{
printf("%c",ch);
}
fclose(fc);
getch();
}
Following program is to open file in read
mode and count no. of lines, semicolons and length of file. While execution
following program you can use source file as ‘C’ or C++ file.
//Program to perform counting operations
#include<stdio.h>
#include<conio.h>
void main()
{
FILE
*fp;
char
sfname[12],ch;
int
line=0,semi=0,len=0;
clrscr();
printf("Enter filename for
counting\n");
gets(sfname);
fp=fopen(sfname,"r");
if(fp
== NULL)
{
printf("File does not exists...\n");
getch();
exit(0);
}
else
{
while((ch=getc(fp))!=EOF)
{
len++; //When ch
is found then at every time len get increment
if(ch
== '\n') //To
check is ch is a new line
{
line++;
}
if(ch == ';') //To
check is ch is a semicolon
{
semi++;
}
}
}
fclose(fp);
printf("Total length of file
=> %d\n",len);
printf("Total line =>
%d\n",line);
printf("Total no. of semicolons
=> %d\n",semi);
getch();
}
Output:
Enter filename for counting
file1.c
Total length of file => 411
Total line => 27
Total no. of semicolons => 14
You can count more things like no. of curly brackets,
no. of spaces and no. of upper case character etc.
String
Input/Output functions:
In addition to fgetc() and fputc(), C
supports the related functions fputs()
and fgets(), which write and read
character strings to and from disk file.
rewind()
whenever we open file in w+ mode then
position of pointer get changed. After writing records you need to read records
so to reset pointer at beginning position rewind()
function is very useful.
The rewind() function resets the file
position indicator to the beginning of the file.
It takes the file pointer to the file, which
is to be rewound as its argument.
//prog to write & read string from file
#include<stdio.h>
#include<conio.h>
void main()
{
FILE *fp;
char str[15];
int i,n;
clrscr();
fp=fopen("c:\\TCC\\string.txt","w+"); //Write and read
mode
printf("Enter how many strings\n");
scanf("%d",&n);
printf("Enter %d strings\n",n);
for(i=0;i<n;i++)
{
printf("Enter any string\n");
flushall();
gets(str);
//to write str into file
fputs(str,fp);
putc('\n',fp); //After storing string new line is
stored
}
rewind(fp); //To set pointer at beginning position for reading string
printf("Content of file\n");
for(i=0;i<n;i++)
{
fgets(str,15,fp); //fgets() has arguments as
string variable, size of string and file pointer
printf("%s",str);
}
fclose(fp);
getch();
}
Output:
Enter how many strings
3
Enter 3 strings
Enter any string
Delhi
Enter any string
London
Enter any string
Mumbai
Content of file
Delhi
London
Mumbai
printf()
and scanf() Functions
These functions are similar to printf() and
scanf() except that they
operate with files.
The prototypes of fprintf() and fscanf()
are:
fprintf(fp,format specifier , list of data
members…);
fscanf(fp, format specifier, address of data
members…);
//structure by using fprintf & fscanf
function
#include<stdio.h>
#include<conio.h>
#define p printf //p defined as a short key for
printf()
#define s scanf //s defined as a short key for
scan()
struct Book
{
int bno;
char name[10];
int price;
}b; //b variable does not have a size because at a time you are
storing single record to a file
void main()
{
FILE *fp;
char ans='y';
clrscr();
fp=fopen("c:\\TCC\\booklist.txt","a"); //Open file in
append mode
while(ans=='y')
{
p("Enter bookno, name &
price\n");
s("%d %s
%d",&b.bno,&b.name,&b.price);
fprintf(fp,"%d %s
%d\n",b.bno,b.name,b.price); //write records to
file
p("Do you have more records?
(y/n)\n");
flushall();
s("%c",&ans);
}
fclose(fp);
fp=fopen("c:\\TCC\\booklist.txt","r");
printf("Records from file are\n");
while((fscanf(fp,"%d %s
%d\n",&b.bno,&b.name,&b.price))!=EOF)
{
p("%d\t %s\t
%d\n",b.bno,b.name,b.price);
}
fclose(fp);
getch();
}
Output:
Enter bookno, name & price
101
Flash
234
Do you have more records? (y/n)
y
Enter bookno, name & price
102
Oracle
420
Do you have more records? (y/n)
n
Records from file are
101 Flash
234
102 Oracle
420
Binary
Files
The information must be interpreted by a
program. These file are not in human readable form.
Information encoded in the binary format.
To handle binary I/O, C provides two
functions, namely fwrite() and fread().
§ fwrite() function is
used to write a block of data to file in a binary form.
§ fread() causes data
to be read from the disk file and placed in an object.
fwrite(&object,
sizeofobject,no.ofobjects,file-pointer);
|
§ The first argument is
address of structure variable.
§ The second argument
is the size of the structure variable in bytes.
§ The third argument is
the number of such arguments we want to write at one time to the file.
§ The last argument is
the pointer to a file.
Random
Access to Files
Whenever we create and initialize file
pointer, then it always starts working from beginning of the file, which is
commonly referred sequential access to a file. All the functions we have
discussed are useful for writing or reading the data sequentially.
However, in many applications we may need to
access particular location in a file or we may need to access particular record
within the file, which is commonly referred as random access to a file. This
task carried out with the help of library functions.
ftell()
|
Returns the position of the file pointer
within the file
|
long ftell(file-pointer)
|
rewind()
|
Places the file pointer at the beginning of
the file.
|
void ftell(file-pointer)
|
fseek()
|
Moves the file pointer to a desired
location.
|
-
|
int fseek(file-pointer, long offset, int
origin);
|
fseek() set file pointer to offset bytes from
the position indicated by origin.
Origin
|
File Location
|
SEEK_SET
or 0
|
Beginning
of file
|
SEEK_CUR
or 1
|
Current
file pointer position
|
SEEK_END
or 2
|
End
of file
|
//structure
by using fwrite() & fread() function
#include<stdio.h>
#include<conio.h>
#define
p printf
#define
s scanf
struct
Book
{
int
bno;
char
name[10];
int
price;
};
struct
Book b;
void
main()
{
FILE
*fp;
char
ans='y';
int
tbno,flag;
clrscr();
fp=fopen("c:\\filebook.txt","ab"); //Open
file in append mode in binary format
while(ans=='y')
{
p("Enter
bookno, name & price\n");
s("%d
%s %d",&b.bno,&b.name,&b.price);
fwrite(&b,sizeof(b),1,fp);
p("you
have more records? (y/n)\n");
flushall();
s("%c",&ans);
}
fclose(fp);
fp=fopen("c:\\filebook.txt","rb");
printf("Records
are\n");
while((fread(&b,sizeof(b),1,fp)))
{
p("%d\t
%s\t %d\n",b.bno,b.name,b.price);
}
fseek(fp,0,SEEK_SET);
//After reading all records pointer is at EOF. So set
it to BOF by using fseek() method for sequential searching operation.
printf("Enter
book no for search\n");
scanf("%d",&tbno);
while((fread(&b,sizeof(b),1,fp)))
{
if(tbno
== b.bno)
{
flag=1; //If
record exists set falg=1 and break a loop
p("Record
found...\n");
p("%d\t
%s\t %d\n",b.bno,b.name,b.price);
break;
}
else
flag=0; //If record does not
exists then flag is always zero
}
if(flag==0)
printf("Record
not found....\n");
fclose(fp);
getch();
}
Output:
Enter bookno, name & price
1
Java
340
you have more records? (y/n)
y
Enter bookno, name & price
2
VB6
200
you have more records? (y/n)
n
Records are
1 Java 340
2 VB6 200
Enter book no for search
2
Record found...
2 VB6 200
Let
us create a big program that handles all types of database operations. You can
say that it is a mini project of ‘C’.
#include<stdio.h>
#include<conio.h>
#define
p printf
#define
s scanf
struct
Bank
{
int
acno;
char
acname[10];
char
type[10];
int
bal;
}b;
void
main()
{
FILE
*fp,*ft;
int
choice,flag,no,amt;
char
ans='y',trans;
clrscr();
while(1) //Infinite
loop
{
p("1.
Open new account\n");
p("2.
List all account\n");
p("3.
Search accont details\n");
p("4.
Deposit\n");
p("5.
Withdraw\n");
p("6.
Exit\n");
p("Enter
your choice\n");
s("%d",&choice);
switch(choice)
{
case
1:
{
fp=fopen("c:\\bank1.txt","ab+");
ans='y';
while(ans=='y')
{
p("Enter
account no\n");
s("%d",&b.acno);
p("Enter
account name\n");
s("%s",&b.acname);
p("Enter
account type\n");
flushall();
s("%s",&b.type);
p("Enter
account amount\n");
s("%d",&b.bal);
fwrite(&b,1,sizeof(b),fp);
p("Do
yo want to add more records?\n");
flushall();
s("%c",&ans);
}
fclose(fp);
break;
}
case
2:
{
fp=fopen("c:\\bank1.txt","rb+");
p("Account
no.\t Name\t Actype\t Bal\n");
p("******************************************\n");
while((fread(&b,1,sizeof(b),fp))!=eof())
{
flushall();
p("%3d\t
%-10s %-10s %3d\n",b.acno,b.acname,b.type,b.bal);
}
fclose(fp);
break;
}
case
3:
{
fp=fopen("c:\\bank1.txt","rb+");
p("Enter
account no for search\n");
s("%d",&no);
while((fread(&b,1,sizeof(b),fp))!=eof())
{
if(no==b.acno)
{
flag=1;
p("Record
found........\n");
p("%3d\t
%-10s\t %-10s\t %3d\n",b.acno,b.acname,b.type,b.bal);
break;
}
else
{
flag=0;
}
}
fclose(fp);
if(flag==0)
{
p("Record
not found.......\n");
}
break;
}
case
4:
{
fp=fopen("c:\\bank1.txt","rb+");
p("Enter
account no for transaction\n");
s("%d",&no);
while((fread(&b,1,sizeof(b),fp))!=eof())
{
if(no==b.acno) //For transaction you
have to search record to set pointer at given location
{
flag=1;
p("Record
found........\n");
p("%3d\t
%-10s\t %-10s\t %3d\n",b.acno,b.acname,b.type,b.bal);
p("Enter
amount for deposition\n");
s("%d",&amt);
b.bal=b.bal+amt;
fseek(fp,-24,SEEK_CUR); //To set file
pointer at current searched location. -24 is used because record size is fixed
as 24 bytes that depends upon data members of structure.
p("Balance
is debited....\n");
fwrite(&b,1,sizeof(b),ft); //Rewrite
the updated record
break;
}
else
{
flag=0;
}
}
fclose(fp);
if(flag==0)
p("Record
not found......\n");
break;
}
case
5:
{
fp=fopen("c:\\bank1.txt","rb+");
p("Enter
account no for transaction\n");
s("%d",&no);
while((fread(&b,1,sizeof(b),fp))!=eof())
{
if(no==b.acno)
{
flag=1;
p("Record
found........\n");
p("%3d\t
%-10s\t %-10s\t %3d\n",b.acno,b.acname,b.type,b.bal);
p("Enter
amount for withdraw\n");
s("%d",&amt);
if(amt>a.bal)
{
b.bal=b.bal-amt;
fseek(fp,-24,SEEK_CUR);
p("Balance
is credited....\n");
fwrite(&b,1,sizeof(b),ft);
}
else
printf(“\nInsufficient
balance…”);
break;
}
else
{
flag=0;
}
}
fclose(fp);
if(flag==0)
p("Record
not found......\n");
break;
}
case
6:
{
exit(0);
}
getch();
}
}
}
When
you create this program then write only
1, 2 and 6 cases first then run it successfully after that insert one by
one case, check it by executing the program. Do not write whole code at a time
otherwise it is very difficult to type and execute. This program will give you
a big output.