Introduction
In the previous chapters we have come across the function scanf ( ) and printf ( ) frequently for entering data from the keyboard and display the result on to the VDU. This works fine when the input data is very small.
But, as the volume of input data increases, in most of the applications, we find it necessary to store the data permanently on the disk and read from it for the following reasons:
1. It is very difficult to input large volume of data through terminals and apart from this it is time consuming to enter such volume of data.
2. If the program is terminated for any of the reason or computer is turned off, the entire data is lost.
To overcome all these problems, the concept of storing the data in disks was introduced. Here, the data can be stored on the disks, the data can be accessed as and when required and any number of times without destroying the data. The data are stored in the form of records and as a file, which is a place on the disk where a group of related data is stored. This chapter deals with various I/O operations on disk after opening a file and before closing. All file operations are achieved using ‘C’ library functions. The functions are classified into following two categories
:- Console input/output functions
Disk input/output functions
The console I/O functions use to receive input from keyboard and display the output on monitor. The Disk I/O functions are use to perform operations on secondary storage devices such as floppy disk or hard disk.
File operations
The various file operations that are performed
are:- Open a file
Read data from the file
Write data to the file
Closing a file
All these operations can be performed either using low-level I/O that uses UNIX system calls, or using high – level I/O library. We shall discuss some of high-level I/O functions provided by C library.
1.
fopen( )The file should be opened before reading a file or before writing into a file.
Syntax:- fp =fopen (char *filename ,char *mode )
Where fp is a file pointer of type FILE, filename holds the name of the file to be opened. The filename should be a valid identifier. Mode details are provided in following table. This informs the library function about the purpose of opening a file.
Return values
file pointer if successful
NULL if unsucessful
The file pointer returned should be of type FILE that is defined in the header file “stdio.h”. The data structure FILE is used to store information about a file. When a file is opened, the function always returns a pointer to the structure FILE. So, before opening a file the following declaration should be used;
FILE *fp;
Where fp is pointer to the structure FILE. Each opened file will have its own FILE structure. Using this file pointer, the necessary data can be accessed from the file. If a file cannot be opened successfully for some reason, the function returns NULL. we can use this NULL character to test whether a file has been successfully opened or not using the statement:
if (fp=NULL)
printf (“Error in opeing the file\n”);
If this condition is not checked, the program may terminate or we may get wrong results.
2. fclose( )
This function is used to close the opened file. A file should be closed when all file operations are over. This ensures that all buffers are flushed and all the links to the file are broken. Once the file is closed, to access the file, it has to be reopened. The syntax is shown below:
Syntax:
Mode Meaning Description
r Read only mode File pointer set to beginning of file (BOF)
w Write only 1. If the file already exists,the contents are lost 2. If file does not exists,a file is created for writing
a Append 1. If the file already exists,file pointer is set to end of file (EOE) in write mode.
2. If the file does not exists,it is created for writing and file pointer is at the beginning.
r+ Read Write Opened for read and write,the file pointer points to beginning of file.
w+ Read Write 1. Opened for read and write,and the file contents are lost if file exists.
2. If file does not exist,the file is read write and file pointer points to beginning of file.
a+ append 1. Opened for read,write and append
2. file pointer is the end of file.
int fclose(FILE *fp)
Where fp is a file pointer. This function returns 0 if successful and EOF on error.
Note :- If the program is terminated, all the opened files will be closed automatically. But, as a programming practice, it is better to close to close all the opened files once we know that the files once we know that the file pointers are not required.
Disk I/O functions:
The disk I/O functions are classified into following categories:
- High level unformatted character I/O
High level unformatted string I/O
High level unformatted string I/O
High level formatted I/O
High Level
Unformatted Formatted
I/O Character
I/O Numeric
I/O String I/O
getc( ) getw( ) fscanf( )
putc( ) putw( ) fprintf( ) ungetc( )
High level unformatted character I/O
It may be sometimes necessary to read or write character to/from disks. The charactter I/O functions are handy at this point of time. This section deals with character I/O functions such as getc( ) and putc( ).
getc( ) and putc( )
getc( ) is a macro defined in stdio.h that gets one character from the file pointer specified. The function putc( ) is also a macro that outputs a character to a file stream specified using file pointer.
Syntax
int getc(FILE *fp);
On success, the function returns the character pointed to file pointer fp. The file pointer fp will automatically point to next character in the input stream. If there is any error or end of file is encountered , the function returns EOF.
The following declaration.
int putc(int ch,ch, FILE *fp);
After success, writes the character stored in ch to the stream pointed to by the file pointer fp. If there is any error or end of-file is encountered, the function returns EOF.
ungetc( ) Syntax:
Disk I/O Functions
int ungetc(int c,FILE *fp);
This function pushes the character read previously using getc() back into input stream pointed to by the file pointer fp. The file pointer fp points to the character pushed. After using getc( ), this function should be used only once. This can be reused again immediately after using getc( ).
On success, this function returns the read character using getc( ) and on faliure, the function ungetc( ) returns EOF.
The program to copy one file to other file is shown in below example using getc( ) and putc( ) macros.
Example: Program to copy one file to other file using getc( ) and putc( )
#include <stdio.h>
#include<process.h>
main () {
FILE *fp1; /* Point to the input files */
FILE *fp2 /Points to the output file */
char file1[10]; /* Name of the input files */
char file2[10] /*Name of the output files */
int ch; /* used to store character read */
printf (“Enter the output file \n);
scanf (“%s”,file1);
/* Open the input file only in read mode */
if ( (fp1=fopen (file1,”r”) )==NULL) {
printf (“Opening input files failed \n);
exit (0);
}
Printf (“Enter the Output file \n);
Scanf (“%s”,file2);
/*Open the output file only in write mode */
fp2=fopen (file_2,”w”);
if (fp2==NULL) {
printf (“Opening outfile failed \n”);
Exit (0);
/* read till end of file is encountered */
while (ch =getc(fp1)!=EOF) {
/* write each character read into output file */
putc (ch,fp2);
}
/* close both input and output file */
fclose (fp1);
fclose(fp2) }
High level unformatted numeric I/O: getw ( ) and putw ( )
The functions getw( ) and putw( ) are integer oriented functions and are similar to the functions getc ( ) & putc( ).
These two functions are used to read arid write integer values.
The syntax of getw ( )is
num =getw (fp);
Where fp is a pointer. An integer is read from the file using file pointer fp and copied into num. Once the integer pointed by fp is read, the file pointer fp automatically points to the next integer in the file.
The syntax of putw( ) is
putw(num,fp);
Where the integer stored is num will be written into the file whose file pointer is fp the program shown in below :- Example:- Reads the numbers from the keyboard and write odd numbers to a file called odd-file and even numbers
to a file called even file.
#include<stdio.h>
void main( ) {
FILE *ifp; /* To store the numbers */
FILE *ofp; /* To store odd numbers in ODD file */
FILE *efp; /* To store EVEN numbers in ODD file */
int n; /* Number of elements to be stored in input file */
int num; /* Numbers to be stored in the input files */
int i; /* Used as a counter */
printf(“Enter the value of n \n”);
scanf(“%d”,&n);
ifp=fopen(“Input”,”w”);
printf(“Enter %d positive numbers and store in the file\n”,n);
for(i=0;i<n;i++) {
scanf(“%d”,&num); /* Read a positive number */
putw(num,ifp); /*Write number into the file */
}
fclose(ifp);
/* Open the input file for reading */
ifp=fopen(“Input”,”r”);
/*Open the odd file for writing */
ofp=fopen(“Odd”,”w”);
/* Open the Even file for writing */
efp=fopen(“Even”,”w”);
/* Read from Input file */
while((num=getw(ifp))!=EOF) {
if(num%2==0) /* Check for even or odd number*/
putw(num,efp); /* Write to Even file */
else
putw(num,ofp); /* Write to Odd file */
}
fclose(ifp);
fclose(ofp);
fclose(efp);
/* Reopen the Odd file in read mode */
printf(“Contents of Odd file\n”);
ofp=fopen(“Odd”,”r”);
/* Display the contents of odd file */
while((num=getw(ofp))!=EOF) {
printf(“%d\n”,num);
}
fclose(ofp);
/* Reopen the Even file in read mode */
printf(“Contents of Even file\n”);
efp=fopen(“Even”,”r”);
/* Display the contents of Even file */
while((num=getw(efp))!=EOF) {
printf(“%d\n”,num);
}
fclose(efp);
}
High level formatted I/O - fscanf( ) & fprintf( )
The functions fscanf( ) and fprintf( ) works exactly in similar way to that of scanf( ) and printf( ) functions. These functions handle mixed data such as integers, characters, floating point numbers etc.
fscanf( )
The syntax of fscanf( ) is:
Syntax:
fscanf(fp,”Control String”,list);
Where fp is a file pointer, control string and list have the same meaning as in scanf( ) i.e., the variables specified in the list will take the values from the file specified by fp using the specifications provided in control string. For example, consider the statement
fscanf(fp,”%d %s %f”,&id,name,&salary);
Here the values for the variables id, name and salary are obtained from the file identified by the file pointer fp. This function returns the number of items that are successfully read fp. This function returns the number of items that are successfully read from the file identified by the file pointer fp.
fprintf( )
The function is similar to that of printf( ) except the syntax. The syntax of fprintf( ) is :
Syntax:-fprintf (fp, ”Control String”, list);
Where fp is a file pointer associated with a file that has been opened for writing. The control string and list have the same meaning as in printf( ) function i.e., the values of the variables specified in the list will be written into the file identified by file pointer fp using the specifications provided in control string. For example, consider the statement
fprintf(fp,”%d %s %f”,id,name,salary);
Here, the values for the variables id, name and salary are written into the file identified by file pointer fp. Consider the program shown in below example. Here the names of employees, the age and salary are written into a file. Also the contents of the file are displayed in the form of a table.
#include<stdlib.h>
#include<stdio.h>
int main( ) {
FILE *fp; //File pointer for the input file.
int n; // Number of employees.
char name[20]; //Name of an employee.
int age; //Holds the age of an employee.
float salary; //Holds the salary of an employee.
int i; //Index variable.
printf(“Enter the number of employees\n”);
scanf(“%d”,&n);
//Open a file in write mode.
fp=fopen(“INPUT”,”w”);
//Obtain employee detail and store in the file.
for(i=0;i<n;i++) {
printf(“Enter name ,age and salary\n”);
//Obtain the name,age,salary from keyboard.
fscanf(stdin,”%s%d%f”,name,&age,&salary);
//Write name,age,salary into the file.
fprintf(fp,”%s%d%f”,name,age,salary);
}
fclose(fp);
//Re-open the file in read mode..
fp=fopen(“INPUT”,”r”);
for(i=0;i<n;i++) {
//Read name,age and salary from the file . fscanf(fp,”%s%d%f”,name,&age,&salary);
//Display name,age and salary on the screen.
fprintf(stdout,”%s%d%f”,name,age,salary);
} }
Error Handling:
During I/O operations, the errors such as:
Reading beyond end of file marker
Unable to open a file
Invalid file name
Attempting to write-protected file etc.,
may occur. Such read and write errors results in abnormal behavior of the [program and so should not be ignored. If proper error checking is not provided, there may be premature termination of program or we may get incorrect output. The functions feof( ) and ferror( ) are used to detect I/O errors in the file.
feof(
):-This function is used to check for end of file. ):-This function accepts file pointer as a parameter and returns either a non zero integer or a zero. If EOF is detected, a non-zero value is returned and if EOF is not detected, zero is returns. For example, if fp points to EOF and the statement
if (feof(fp))
Printf (“End of file is reached\n”);
ferror (
):-This macro is used to get the status of a file. ):-This function accepts file pointer as a parameter and returns a non-zero value if an error is detected and zero otherwise. For example, the statement
if (ferror(fp )!=0)
printf (“Error in the file”);
displays the message “Error in the file” if there is an error in opening /reading/writing the file identified by fp. The program shown in below example provides how error-handling functions are used.
Example: -‘C’ program which provides error handling in files: -
#include<stdio.h>
#include<process.h>
printf(“Enter the file name:-\n”);
scanf(“%s”,file1);
pintf(“\nVery few characters are present in file:-\n”);
exit(0);
In the above program, assume that file exists and is opened successfully. Using for loop, 30 characters have to be printed. But, if the file does not have so many characters, feof macro detects end of file of file and the message
“Very few characters are present in the file” is displayed. If end of file is not reached, the first 30 characters from the input file are displayed.
Random access to files(File control
functions):-The various file functions so far discussed read/write data sequentially. In some situations it may be necessary to point the file pointer to a specific position in the file. The various functions such as ftell( ), fseek( ), rewind ( ) are used for this specific purpose.
ftell(
):-This function is used to obtain the current position of the file pointer. The syntax is:
long ftell (FILE* fp);
This function returns the current position of the file pointer on success and EOF on error. If this function return 1000, it indicates that 999characters have been read so far from the file and file pointer fp is pointing to the 1000th character in the file.
fseek (
):-This function is used to reposition the file pointer i.e. it is used to move the file pointer to the desired position within the file.
Syntax
int fseek (FILE *fp, long offset, int start-point);
Where
fp is file pointer.
offset can take positive, negative or zero value and specifies the number or bytes to be moved from the location specified by start-point.
Start-point can take one of the values. 0 indicates from beginning of the file, 1 indicates from the current position and 2 indicate from the end of file.
This function returns 0 on success and non-zero value on failure. If offset is positive, the file pointer moves forwards.
If it is negative, the file pointer moves backwards. For example –
fseek (fp,0,0) - file pointer moves to the beginning of the file
fseek(fp,0,1)-file pointer stays in the current position and is rarely used
fseek(fp,0,2)-file pointer moves to the end of file
fseek(fp,n,0)-file pointer moves n bytes from the beginning of the file
fseek(fp,n,1)-file pointer moves n bytes from the current position of file pointer
fseek (fp,-n,1)-file pointer moves n bytes backwards from the current position of file pointer
fseek(fp,-n,2)-file pointer moves n bytes backwards from the end of file.
rewind (
):-This function accepts file pointer as a parameter and resets the position of the file pointer to the start of the file. For example, if file pointer fp is in position 1000, by executing the
rewind(fp);
the file pointer fp is set to the very first position in the file. Note that the position of the first byte is 0, position of second byte is 1, the position of third byte is 2 and so on. Once a file is completely read the file pointer points to the end of file. By using this function, a file can be read more than once without closing and opening the file.
The program shown in below example finds the size of a given file and uses all the file control functions discussed.
Example:- ‘C’ program to print the size of a given file:-
#include<stdio.h>
#include<process.h>
//function definition starts...
long file_size(FILE *fp) {
long curpos, length;
//Returns the current position of file pointer . curpos=ftell(fp);
// Move file pointer from begining of the file to EOF.
fseek(fp,0L, 2);
/* Obtain the current position of file pointer */
length=ftell(fp);
/* File pointer from the current position to the beginning. */
rewind(fp); // We can also use fseek(fp,curpos,0);
return length;
}
// main function starts...
main() {
FILE *fp;
char file_name[20];
printf(“Enter the file name:-“0;
scanf(“%s”,file_name);
fp=fopen(file_name,”r”);
if(fp==NULL ) {
printf(“Error in opening file\n”);
exit(0);
}
printf(“Filesize of %s is %ldbytes\n”,file_name,filesize(fp);
fclose(fp);
}
The program is self –explanatory with appropriate comments and the reader should read and understand the logic.
Note: What is the difference between rewind (fp) and fseek (fp,0L,0) ? The answer is that ‘.’Functionality is same, but syntax and number of parameters are different”
Display contents of file
:-Now, let us write a program to display the contents of file. The file if specified in the command line, the user should be prompted for the file and that file should be opened and displayed. The complete program is shown in below example.
Example:- ‘C’ program to accept a file through command line or as specified by user during run and display the contents:-
#include<stdio.h>
#include<process.h>
#include<string.h>
void main(int argc, char *argv[ ]) {
FILE *fp; //File [pointer used to display a file.
char fname[10]; //File to be opened and displayed.
char ch; // Holds the character to be displayed.
if(argc==1) {
/*No command line file name..*/
printf(“Enter the file name:-“);
scanf(“%s”,fname);
} else {
/* Command line file exist */
strcpy(fname,argv[1]);
printf(“The contents of the file are:\n...\n”);
//File opened successfully and display the contents.
while((ch=getc(fp))!=EOF)
The contents of file are:-...
Hello how are you
This is the first program using command line arguments.
Good Luck Have Fun
Output:-c:\>disp
Enter the file name:- Hello The contents of file are:-...
Hello how are you
This is the first program using command line arguments.
Good Luck Have Fun
Note: The file name of this program is “disp.c” Before executing this program make sure that the file by name “Hello”
exists in the current directory from where you are running the executable file “disp”. Also make sure that some text is stored in the file “Hello”. In the first output argv [0] corresponds to disp and argv [1] corresponds to the string
“Hello” In the second output argv [1] is NULL.
In this program, in the beginning of the function main we are checking whether a file has been specified in the command line. If file not specified, the value of argc will be 1 and so the user is prompted to enter the file name during run time. But, if the value of argc is greater than 1, the control comes to else statement and the file specified
in the command line is copied to fname which will be used for opening. Reset of the statements in the program is self-explanatory.
Obtain text and create file (use only command line parameters)
Let us consider another program where to accept a file followed by a text only through command line parameters.
The C program shown in below example achieves this and is self-explanatory using appropriate comments.
Example:- ‘C’ Program to accept a file and text through command arguments and create a file with the text
#include<stdio.h>
#include<process.h>
#include<string.h>
#include<string.h>