File Handling in C

1. What are the various file handling function in C?

File is a collection of data stored in a secondary storage device.

A file can be either a text file or a binary file. A text file is human readable but is not very compact.

The library functions used for file handling are
  • fopen() - used to open a file
  • fclose() - used to close a file
  • fscanf() - used to read from a text file
  • fprintf() - used to write to a text file
  • feof() - used to check if end of file is reached
  • fseek() - used to move the file pointer to an offset from begining or end or current location
  • ftell() - used to give the location of file pointer
  • fread() - used to read from a binary file
  • fwrite() - used to write to a binary file
All the file handling functions make use of a pointer to the type FILE which is defined in stdio.h. fopen returns a file pointer after successful opening of the file.
2. What are different modes of opening a file? What does file open command return?

A file can be opened in read, write and append modes.

  FILE*  fopen(char *file-name,char *mode)

mode --
  • r - reading
  • w - writing
  • a - appending
  • r+ w+ a+ - read and write
  • b - binary file
The file open function (fopen) returns a file pointer- a pointer to FILE type.

If the the file open is not successful, then fopen() returns NULL.

e.g. To open a file one.c for reading, we can use the following code.
   FILE *fptr = fopen("one.c","r");
   
To open the file two.c for appending, we can write
   FILE *fptr = fopen("two.c","a");
   
An open file can be closed using the fclose() function. e.g.
   fclose(fptr):
   
3. How do you read from a file? How do you write to a file?

After opening a file, to read from a file, we can use these following functions.
  1.    fscanf(FILE *ptr,const char *format,...)
    This is similar to scanf() function, but the first argument must be a file pointer. It uses the format specifiers for each value to be read. e.g.
       FILE *fptr = fopen("a.txt","r");
       fscanf(fptr,"%d %d %f",&a,&b,&c);
    
  2. char fgetc(FILE *ptr)
    
      char ch = fgetc(fptr)
    
    This reads one character from a file. And it returns the character read or EOF if end of file is reached.
  3.  fgets(FILE *ptr,int len,char *string)
    This reads one line or maximum of len characters from the file and stores it in string.
    char s[80];
    fgets(fptr,79,s);
    
  4. fread(char *ptr,sizeof(a),n,fptr)
    This reads n values from a binary file and it returns the number of bytes successfully read. The first parameter is the address of data to be read. It should be typecast to character pointer.
4. How do you write to a file?

To write to a file, we can use the following functions.
fprintf(FILE *ptr,char *format,...)
fputs(FILE*ptr, char *string);
fputc(FILE *ptr,char ch)
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
  • fprintf() is similar to printf - it stores the values in formatted way. First parameter must be FILE pointer
    fprintf(fptr,"%d %d are values",a,b);
  • fputs() writes a string to the file followed by a newline character.
    char *s="Hello world";
    fputs(s,fptr);
    
  • fputc() writes one character to the file.
    char ch = 'a';
    fputc(ch,fptr);
    
  • fwrite() writes values to a binary file.
    int a = 10
    fwrite(&a,sizeof(a),1,fptr); 
    
    The first parameter must be address of the variable to be written typecast to char pointer.
5. Write a program to count the number of characters, words and lines present in a file. If filename is not given, it should take from standard input

#include<stdio.h>
#include<string.h>
int num_words(char *str)
{
    int num = 0;
    while(*str!='\n')
    {
      while(*str==' '|| *str=='\t')
         str++;
      /*absorb consecutive space/tab etc*/   
      while(*str!='\n' && *str!=' '&&*str!='\t')
         str++;
      /*go till end of the word*/   
      num++;
    }
    return num;
}
int num_chars(char *str)
{
     int n=0;
     while(*str!='\n')
     {  
        n++;
        str++;
     }
     /* we can also use strlen -1*/
    return n+1;
}
    
void readfile(FILE *fptr)
{
    int lines = 0,words=0,count=0;
    char ch;
    while(!feof(fptr))
    {
       char line[100];
       int nc,nw;
       char *ptr = fgets(line,99,fptr);
       if(ptr==NULL)
           break;
       nc = num_chars(line);
       nw = num_words(line);
       
       words+=nw;
       count+=nc;
       lines++;
      }  
    printf("words = %d lines=%d chars = %d",words,lines,count);
}
int main(int argc,char *argv[])
{

    FILE *fptr;
    char filename[25];
    if(argc>1)
       strcpy(filename,argv[1]);
    else
     {
         printf("Enter file name:");
         scanf("%s",filename);
     }
    fptr = fopen(filename,"r");
    if(fptr==NULL)
    {
       printf("File open error");

     }
     else
     {
         readfile(fptr);
         fclose(fptr);
     }
     return 0;
}
6. Write a program to print the size of a text file in bytes where filename is given with command line.

#include<stdio.h>
int main(int argc,char *argv[])
{

    FILE *fptr;
    int n;
    if(argc<=1)/*argument count is 1. Name of file not specified*/
    {
          printf("Please provide filename as command line argument:'");
          return 0;
     }
     fptr = fopen(argv[1],"r");
     if(fptr==NULL)
     {
        printf("Unable to open file");
        return 0;
      }
      fseek(fptr,0L,SEEK_END);
      n = ftell(fptr);
      printf("Size of file is %d bytes\n",n);
      return 0;
}
7. Write a program to read a file name and a word and print all lines in the file which contain that word.

#include<stdio.h>
#include<string.h>
void searchword(FILE *fptr,char *word)
{

    while(!feof(fptr))
    {
       char str[100];
       if(fgets(str,99,fptr)==NULL)
          break;
       if(strstr(str,word)!=NULL)
          printf("%s",str);
      }

}
int main(int argc,char *argv[])
{

    FILE *fptr;
    char filename[25];
    char word[30];
    if(argc<2) 
     {
        printf("Please provide file name as command line parameter");
       return 1;
     }

    fptr = fopen(argv[1],"r");
    if(fptr==NULL)
    {
       printf("File open error");

     }
     else
     {
        searchword(fptr,argv[2]);
         fclose(fptr);
     }
     return 0;
}
8. Write a function to print last 10 lines of a text file.

 
#include
void read_n_lines(FILE *fptr,int num_lines)
{
     int count = 0;
     char str[81];
     int offset = -1;  
     int ch;  
     fseek(fptr,offset,SEEK_END);
   	  while(count < num_lines && ftell(fptr)!=0)
   	  {
   	  	    ch =  fgetc(fptr);
   	  	     if(ch=='\n')
   	  	     {
   	  	     	count++;
   	  	     	if(count==num_lines)
   	  	     	   break;
   	  	     }
   	  	     fseek(fptr,--offset,SEEK_END);
   	 }
   	 while(fgets(str,80,fptr)!=NULL)
   	      printf("%s",str);
   }   	      	     
 
We are moving the file pointer to end of file. And then read one character at a time. Each time we decrement offset and use fseek to move file pointer to offset. When ever a new line character is read, we increment the count. When count reaches num_lines, we terminate the loop without moving the file pointer.

Now the file pointer is located before 10th line from end of file or at the begining of the file, if there are no 10 lines. Now we just read one line at a time using fgets and display this line on screen.

We should call this function with file pointer as first parameter and 10 as second parameter.
9. Write a program to store 3 structures to a binary file.

To open a binary file for writing, we must use "wb" as second parameter to fopen.

To write the structure array to the binary file, we can use fwrite function with address of array as first parameter, size of one element of array as second parameter, size of the block - in this case 3 as the third parameter and file pointer as fourth parameter.

#include<stdio.h>
struct book
{
    char name[200];
    char author[100];
    float price;
};
int main()
{
    struct book bk_array[]={ {"C programming language","Kernighan & Ritchie",214},
                    {"Let us C","Yeshawant Kanetkar",189},
                    {"Teach yourself C in 21 days","ABCD",329} };
    FILE *fptr;
    char filename[40];
    printf("Filename=");
    scanf("%s",filename);
    fptr = fopen(filename,"wb");
    if(fptr==NULL)
    {
          printf("File open error");
          return 1;
    }
    fwrite(bk_array,sizeof(bk_array[0]),3,fptr);
    fclose(fptr);
    return 0;
}
10. Write a program to read the filename from user and display the contents of that file

#include<stdio.h>
#include<stdlib.h>
int main()
{
   FILE *fptr;
   char *filename;
   filename = (char*)malloc(30);
   printf("Filename :");
   scanf("%s",filename);
   fptr = fopen(filename,"r");
   if(fptr==NULL)
     printf("file open error");
   else
   {
      while(!feof(fptr))
      {
        char ch = fgetc(fptr);
        putchar(ch);
      }
      fclose(fptr);
   }
   return 0;
}
11. Write a program to read names,ids and salaries of 10 people and store them in a binary file

#include<stdio.h>
struct emp
{
   int id;
   char name[30];
   float salary;
};
void readEmpDetails(struct emp arr[],int size)
{
   int i;
   for(i=0;i<size;i++)
   {
     printf("Id, name and salary of employee%d:",i);
     scanf("%d %s %f",&arr[i].id,arr[i].name,&arr[i].salary);
   }
}

int main()
{
    struct emp arr[20];
    int num,nItems;
    FILE *fptr;
    printf("Enter number of employees:");
    scanf("%d",&num);
    readEmpDetails(arr,num);
    
    fptr = fopen("empl.txt","wb");
    if (fptr!=NULL){ 
       nItems = fwrite((void*)arr,sizeof(struct emp),num,fptr);     
       if(nItems!=0)
             printf("File successfully written");
       fclose(fptr);
    }
    else
      printf("File open error");
   return 0;
}
12. Write a program to copy one file to another using fputc command.

#include<stdio.h> 
int main()
{  
    FILE *fptr1,*fptr2;
    char filename1[30],filename2[30];
    printf("Enter source file:");
    scanf("%s",filename1);
    printf("Enter destination file:");
    scanf("%s",filename2);
    if( (fptr1 =fopen(filename1,"r"))==NULL)
        printf("Error opening %s",filename1);
    else if( (fptr2=fopen(filename2,"w"))==NULL)
        printf("Error opening %s",filename2);
    else
    {
       /*both files are opened*/
        char ch;
        while ( (ch=fgetc(fptr1))!=EOF)
           fputc(ch,fptr2);
        fclose(fptr1);
        fclose(fptr2);
     
    }  
   return 0;
}
13. Write a program to read two files and print the first lines which are different in these files.
The program must emulate diff command.

#include<stdio.h>
#include<string.h>
void compareFiles(FILE *f1,FILE *f2)
{
    while(!feof(f1)&& !feof(f2))
    {
       char str1[80],str2[80];
       char *ptr1, *ptr2;
       ptr1 = fgets(str1,79,f1);
       ptr2 = fgets(str2,79,f2);
       if(ptr1!=NULL && ptr2!=NULL)
           if( strcmp(str1,str2)!=0)
           {
                printf("The different lines are %s %s",str1,str2);
                return;
           }
     } 
    printf("The two files are similar");
}
int main()
{  
    FILE *fptr1,*fptr2;
    char filename1[30],filename2[30];
    printf("Enter first file:");
    scanf("%s",filename1);
    printf("Enter second file:");
    scanf("%s",filename2);
    if( (fptr1 =fopen(filename1,"r"))==NULL)
        printf("Error opening %s",filename1);
    else if( (fptr2=fopen(filename2,"r"))==NULL)
        printf("Error opening %s",filename2);
    else
    {
        compareFiles(fptr1,fptr2);     
    }  
   return 0;
}
14. Write a function, which reads a binary file with n numbers , stores the even items of file (2nd, 4th,6th..) in one binary file and odd items (1st, 3rd, 5th...) in second binary file.

void read_file(FILE *fptr,FILE *fptrout1,FILE *fptrout2)
{
    int i=1;
    int n;
    while(!feof(fptr))
    {
        fread(&n,sizeof(n),1,fptr);//fread used for binary files
        if(i%2==0)
        {
          fwrite(&n,sizeof(n),1,fptrout2);
        }
        else
          {
             fwrite(&n,sizeof(n),1,fptrout1 );
          }
       i++;
    }
    fclose(fptr);
    fclose(fptrout1);
    fclose(fptrout2);
}