Tuesday 14 March 2017

FILES CONCEPT IN C




1.     Definition of files
2.     File using functions
3.     fopen and fclose functions
4.     character input /output functions
5.     String input and output functions
6.     Sequential vs random access files.
7.     Positioning the file pointers

Why files are needed?

When the program is terminated, the entire data is lost in C programming. If you want to keep large volume of data, it is time consuming to enter the entire data. But, if file is created, this information can be accessed using few commands.
There are large numbers of functions to handle file I/O in C language. In this study material, you will learn to handle standard I/O (High level file I/O functions) in C.
High level file I/O functions can be categorized as:
  1. Text file
  2. Binary file

File Operations

  1. Creating a new file
  2. Opening an existing file
  3. Reading from and writing information to a file
  4. Closing a file

Working with file

While working with file, you need to declare a pointer of type file. This declaration is needed for communication between file and program.
FILE *ptr;

fopen() and fclose() functions

Opening a file

Opening a file is performed using library function fopen(). The syntax for opening a file in standard I/O is:
ptr=fopen("fileopen","mode")
 
For Example:
SYNTAX:- 
            fopen("E:\\cprogram\program.txt","w"); 
  
/* --------------------------------------------------------- */
 E:\\cprogram\program.txt is the location to create file.   
 "w" represents the mode for writing.
/* --------------------------------------------------------- */
Here, the program.txt file is opened for writing mode.
Opening Modes in Standard I/O
File Mode
Meaning of Mode
During Inexistence of file
r
Open for reading.
If the file does not exist, fopen() returns NULL.
w
Open for writing.
If  the file exists, its contents are overwritten. If the file does not exist, it will be created.
a
Open for append. i.e, Data is added to end of file.
If the file does not exists, it will be created.
r+
Open for both reading and writing.
If the file does not exist, fopen() returns NULL. 
w+
Open for both reading and writing.
If  the file exists, its contents are overwritten. If the file does not exist, it will be created.
a+
Open for both reading and appending.
If the file does not exists, it will be created.

Closing a File

The file should be closed after reading/writing of a file. Closing a file is performed using library function fclose().
SYNTAX:-
            fclose(ptr); //ptr is the file pointer associated with file to be closed.

The Functions fprintf() and fscanf() functions.

Important is that the functions fprintf() and fscanf() are the file version of printf() and fscanf(). The only difference while using fprintf() and fscanf() is that, the first argument is a pointer to the structure FILE

Character input /output functions ,String input and output functions
Examples:-

Writing to a file

#include <stdio.h>
int main()
{
   int n;
   FILE *fptr;
   fptr=fopen("C:\\program.txt","w");
   if(fptr==NULL){
      printf("Error!");   
      exit(1);             
   }
   printf("Enter n: ");
   scanf("%d",&n);
   fprintf(fptr,"%d",n);   
   fclose(fptr);
   return 0;
}
 
This program takes the number from user and stores in file. After you compile and run this program, you can see a text file program.txt created in C drive of your computer. When you open that file, you can see the integer you entered.
Similarly, fscanf() can be used to read data from file.

Reading from file

 
#include <stdio.h>
int main()
{
   int n;
   FILE *fptr;
   if ((fptr=fopen("C:\\program.txt","r"))==NULL){
       printf("Error! opening file");
       exit(1);         /* Program exits if file pointer returns NULL. */
   }
   fscanf(fptr,"%d",&n);
   printf("Value of n=%d",n); 
   fclose(fptr);   
   return 0;
}
 
If you have run program above to write in file successfully, you can get the integer back entered in that program using this program.

Other functions like fgetchar(), fputc() etc. can be used in similar way.

Description

The C library function int fputc(int char, FILE *stream) writes a character (an unsigned char) specified by the argument char to the specified stream and advances the position indicator for the stream.

Declaration

Following is the declaration for fputc() function.
SYNTAX:- 
               int fputc(int char, FILE *stream)

Parameters

·         char -- This is character to be written. This is passed as its int promotion.
·         stream -- This is the pointer to a FILE object that identifies the stream where the character is to be written.

Return Value

If there are no errors, the same character that has been written is returned. If an error occurs, EOF is returned and the error indicator is set.

Example

The following example shows the usage of fputc() function.

#include <stdio.h>

int main ()
{
   FILE *fp;
   int ch;

   fp = fopen("file.txt", "w+");
   for( ch = 33 ; ch <= 100; ch++ )
   {
      fputc(ch, fp);
   }
   fclose(fp);

   return(0);
}

Let us compile and run the above program, this will create a file file.txt in the current directory which will have following content:
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcd

Now let's the content of the above file using the following program:

#include <stdio.h>

int main ()
{
   FILE *fp;
   int c;

   fp = fopen("file.txt","r");
   while(1)
   {
      c = fgetc(fp);
      if( feof(fp) )
      {
          break ;
      }     
      printf("%c", c);
   }
   fclose(fp);
   return(0);
}

Binary Files

Depending upon the way file is opened for processing, a file is classified into text file and binary file.
If a large amount of numerical data it to be stored, text mode will be insufficient. In such case binary file is used.
Working of binary files is similar to text files with few differences in opening modes, reading from file and writing to file.

Opening modes of binary files

Opening modes of binary files are rb, rb+, wb, wb+,ab and ab+. The only difference between opening modes of text and binary files is that, b is appended to indicate that, it is binary file.

Reading and writing of a binary file.

Functions fread() and fwrite() are used for reading from and writing to a file on the disk respectively in case of binary files.
Function fwrite() takes four arguments, address of data to be written in disk, size of data to be written in disk, number of such type of data and pointer to the file where you want
to write.
 
Syntax:- 
            fwrite(address_data,size_data,numbers_data,pointer_to_file);

Function fread() also take 4 arguments similar to fwrite() function as above.

 

Sequential and Random Access File Handling in C


In computer programming, the two main types of file handling are:
·         Sequential;
·         Random access.
Sequential files are generally used in cases where the program processes the data in a sequential fashion – i.e. counting words in a text file – although in some cases, random access can be feigned by moving backwards and forwards over a sequential file.
True random access file handling, however, only accesses the file at the point at which the data should be read or written, rather than having to process it sequentially. A hybrid approach is also possible whereby a part of the file is used for sequential access to locate something in the random access portion of the file, in much the same way that a File Allocation Table (FAT) works.
The three main functions are:
·         rewind() – return the file pointer to the beginning;
·         fseek() – position the file pointer;
·         ftell() – return the current offset of the file pointer.
Each of these functions operates on the C file pointer, which is just the offset from the start of the file, and can be positioned at will. All read/write operations take place at the current position of the file pointer.
The rewind() Function
The rewind() function can be used in sequential or random access C file programming, and simply tells the file system to position the file pointer at the start of the file. Any error flags will also be cleared, and no value is returned.
While useful, the companion function, fseek(), can also be used to reposition the file pointer at will, including the same behavior as rewind().
Using fseek() and ftell() to Process Files-àPositioning the file pointers
The fseek() function is most useful in random access files where either the record (or block) size is known, or there is an allocation system that denotes the start and end positions of records in an index portion of the file. The fseek() function takes three parameters:
·         FILE * f – the file pointer;
·         long offset – the position offset;
·         int origin – the point from which the offset is applied.
The origin parameter can be one of three values:
·         SEEK_SET – from the start;
·         SEEK_CUR – from the current position;
·         SEEK_END – from the end of the file.
So, the equivalent of rewind() would be:
fseek( f, 0, SEEK_SET);
By a similar token, if the programmer wanted to append a record to the end of the file, the pointer could be repositioned thus:
fseek( f, 0, SEEK_END);
Since fseek() returns an error code (0 for no error) the stdio library also provides a function that can be called to find out the current offset within the file:
long offset = ftell( FILE * f )
This enables the programmer to create a simple file marker (before updating a record for example), by storing the file position in a variable, and then supplying it to a call to fseek:
long file_marker = ftell(f);
// … file processing functions
fseek( f, file_marker, SEEK_SET);
Of course, if the programmer knows the size of each record or block, arithmetic can be used. For example, to rewind to the start of the current record, a function call such as the following would suffice:
fseek( f, 0 – record_size, SEEK_CURR);
With these three functions, the C programmer can manipulate both sequential and random access files, but should always remember that positioning the file pointer is absolute. In other words, if fseek is used to position the pointer in a read/write file, then writing will overwrite existing data, permanently.
ERROR HANDLING IN FILES:-
In this C language study material I am going to look at error handling. Although C programming does not provide direct support for error handling (also called exception handling), there are ways to do error handling.
Of course the programmer needs to prevent errors during coding and should always test the return values of functions called by the program. A lot of C function calls return a -1 or NULL in case of an error, so quick test on these return values are easily done with for instance an ‘if statement’.
For instance if a program successful ends the return value of the program is zero. If the program ends with an error usually a number larger than zero is returned (for example 1).
So, the one thing you need to remember is that you (the programmer) are responsible for error handling. You’re the person that needs to make sure that a program will gracefully terminate and not just CRASH unexpectedly! It is you that need to take appropriate action depending on the return values of function calls.

Global Variable errno

The global variable errno is used by C functions and this integer is set if there is an error during the function call. To make use of errno you need to include errno.h and you need to call ‘extern int errno;’
Let us take a look at an example:

#include <stdio.h>
#include <errno.h>
extern int errno;
int main () {
        FILE * fp;
        fp = fopen ("filedoesnotexist.txt", "rb");
        if (fp == NULL) {
                    fprintf(stderr, "Value of errno: %d\n", errno);
        } else {
                    fclose (fp);
        }
        return 0;
}
The output of the program will be something like:
Value of errno is: 2
As you can see we include the stdio.h and errno.h header files. Then ‘extern int errno’ is called, so we now have access to the integer errno. To generate an error we open a file that doesn’t exist. If the file pointer (fp) equals NULL then we print the value of errno (in this case errno will be 2). If we get a file pointer (in case the file exists) we close the file.

The functions strerror() and perror()

In the previous example the errno had a value of 2. But what is the meaning of the value of 2? How does the user know what this error is? Of course a good practice is to make some documentation where you describe each error number and what the user should do. But it is also a good practice to give a good descriptive error message when an error occurs in the program. The C programming language has two functions that can be used to display a text message that is associated with errno. The functions are strerror() and perror().
The function strerror() returns a pointer to the textual message of the current errno value. The function perror() displays a string you pass to it, followed by a colon and the textual message of the current errno value.
-----------------------------This ends the basic File concepts---------------------------------------

Basic C- Files Examples:-
    1. Write a C program to read name and marks of n number of students from user and store them in a file.
#include <stdio.h>
#include<conio.h>
int main(){
   char name[50];
   int marks,i,n;
   clrscr();
   printf("Enter number of students: ");
   scanf("%d",&n);
   FILE *fptr;
   fptr=(fopen("C:\\student.txt","w"));
   if(fptr==NULL){
       printf("Error!");
       exit(1);
   }
   for(i=0;i<n;++i)
   {
      printf("For student%d\nEnter name: ",i+1);
      scanf("%s",name);
      printf("Enter marks: ");
      scanf("%d",&marks);
      fprintf(fptr,"\nName: %s \nMarks=%d \n",name,marks);
   }
   fclose(fptr);
   getch();
   return 0;
}

    1. Write a C program to read name and marks of n number of students from user and store them in a file. If the file previously exits, add the information of n students.
#include <stdio.h>
#include<conio.h>
int main(){
   char name[50];
   int marks,i,n;
   clrscr();
   printf("Enter number of students: ");
   scanf("%d",&n);
   FILE *fptr;
   fptr=(fopen("C:\\student.txt","a"));
   if(fptr==NULL){
       printf("Error!");
       exit(1);
   }
   for(i=0;i<n;++i)
   {
      printf("For student%d\nEnter name: ",i+1);
      scanf("%s",name);
      printf("Enter marks: ");
      scanf("%d",&marks);
      fprintf(fptr,"\nName: %s \nMarks=%d \n",name,marks);
   }
   fclose(fptr);
   getch();
   return 0;
}  

    1. Write a C program to write all the members of an array of strcures to a file using fwrite(). Read the array from the file and display on the screen.

#include<stdio.h>
#include<conio.h>
struct s
{
char name[50];
int height;
};
int main(){
    struct s a[5],b[5];  
    FILE *fptr;
    int i;
clrscr();
    fptr=fopen("file.txt","wb");
    for(i=0;i<5;++i)
    {
        fflush(stdin);
        printf("Enter name: ");
        gets(a[i].name);
        printf("Enter height: ");
        scanf("%d",&a[i].height);
    }
    fwrite(a,sizeof(a),1,fptr);
    fclose(fptr);
    fptr=fopen("file.txt","rb");
    fread(b,sizeof(b),1,fptr);
    for(i=0;i<5;++i)
    {    printf("Name: %s\nHeight: %d",b[i].name,b[i].height);
    }
    fclose(fptr);
getch();
}