Module 7. File handling

Lesson 18

FILE HANDLING IN ‘C’

18.1  Introduction

Real life situations involve large volumes of data. In such cases, the console (keyboard) oriented I/O operations create two major problems: a) it becomes cumbersome and time consuming to handle large volumes of data through terminals; and b) the entire data is lost when either the programme is terminated or computer is turned off. Thus, it is necessary to have more flexible approach where data can be stored on the disks and read whenever necessary, without destroying the data. This method employs the concept of files to store data.

In this section, you will learn about files, which are very important for storing information permanently. You store information in files for many purposes like data processing by your programmes.

What is a File?

A file is a collection of bytes stored on a secondary storage device, which is generally a disk of some kind. The collection of bytes may be interpreted, for example, as characters, words, lines, paragraphs and pages from a textual document; fields and records belonging to a database; or pixels from a graphical image. The meaning attached to a particular file is determined entirely by the data structures and operations used by a programme to process the file. A file is simply a machine decipherable storage medium where programmes and data are stored for machine usage. Essentially, there are two kinds of file that programmers deal with text files and binary files.

ASCII Text Files

A text file can be a stream of characters that a computer can process sequentially. It is not only processed sequentially but only in forward direction. For this reason a text file is usually opened for only one kind of operation (reading, writing, or appending) at any given time.

Similarly, since text files only process characters, they can only read or write data one character at a time. However, ‘C’ provides several functions that deal with lines of text, but these still essentially process data one character at a time. A text stream in ‘C’ is a special kind of file. Depending on the requirements of the operating system, newline characters may be converted to or from carriage-return/linefeed combinations depending on whether data is being written to, or read from, the file. Other character conversions may also occur to satisfy the storage requirements of the operating system. These translations occur transparently and they occur because the programmer has signalled the intention to process a text file.

Binary Files

A binary file is similar to a text file. It is a collection of bytes. In ‘C’, a byte and a character are equivalent. Hence, a binary file is also referred to as a character stream, but there are two essential differences.

1.      No special processing of the data occurs and each byte of data is transferred to or from the disk unprocessed.

2.      ‘C’ places no constructs on the file, and it may be read from, or written to, in any manner chosen by the programmer.

Binary files can be either processed sequentially or, depending on the needs of the application, they can be processed using random access techniques. In ‘C’, processing a file using random access techniques involves moving the current file position to an appropriate place in the file before reading or writing data. This indicates a second characteristic of binary files. They a generally processed using read and write operations simultaneously. For example, a database file will be created and processed as a binary file. A record update operation will involve locating the appropriate record, reading the record into memory, modifying it in some way, and finally writing the record back to disk at its appropriate location in the file. Such operations are common to many binary files, but are rarely found in applications that process text files.

18.2  Reading and Writing Files

This section describes as to how to read from and write onto files in ‘C’. All file functions need stdio.h header file to work properly. The first thing you need to know about is file pointers. File pointers are like any other pointer, but they point to a file. You define a file pointer as follows:

FILE *filepointer;

The type FILE is used for a file variable and is defined in the stdio.h file. It is used to define a file pointer for use in file operations. A list of file operation functions along with their purposes is given in Table-18.1 below. 

Table 18.1 File operation functions

Function Name

Operation

fopen

Creates a new file. Opens an existing file.

fclose

Closes 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 to a file

fscanf

Reads a set of data values from a file

getw

Reads a integer from a file

putw

Writes an integer to the file

fseek

Sets the position to a desired point in the file

ftell

Gives the current position in the file

rewind

Sets the position to the beginning of the file

 

Before you write to a file, you must open it. This indicates to the system that you want to write to a file and you also define its file name with the fopen function illustrated below. The file pointer, e.g., filepointer in the following example, points to the file and two arguments are required in the parentheses, i.e., the file name, followed by the file type as follows:

filepointer = fopen("filename", "mode");

fopen returns a file pointer. It returns NULL if the file does not exist. fopen takes the first argument as the filename to open. It needs to be of string type. The second argument is the mode argument.Mode specifies what you want to do with the file. Some modes are: "r" - read the file; "w" - write the file; "a" - append to the file; "r+" - read and write to the file; "w+" - read and write, overwrite the file; and "a+" - read and write, append. These modes will open files in text mode. Files opened in text mode have some bytes filtered out. If you want to open binary files, use binary mode by adding a "b" to the mode. For example: "rb" - read the file in binary mode. To read a character from a file, you use fgetc. It is like getchar, but for files. It works like this:

character = fgetc(filepointer);

fgetc returns the character that is read from the file as an integer. fgetc takes the file pointer as its only input. It will automatically increment the pointer to read the next character. fputc allows you to write a character to a file:

fputc(character, filepointer);

fputc takes an unsigned char as the first argument and the file pointer as the second argument. fputc returns EOF on failure. You can also use fprintf and fscanf. They work like printf and scanf, except the file pointer is the first argument. They work like this:

//writes hello world to the file

fprintf(filepointer, "Hello, World!\n");

//reads an integer from the file

fscanf(filepointer, "%d", integer);

In order to close the file again, you must use fclose. It looks like this:

fclose(filepointer);

fclose closes the file that filepointer points to.

Example 1: Programme to read a file.

The following programme reads a file entered by the user and displays its contents on the screen, fopen function is used to open a file; it returns a pointer to structure FILE. FILE is a predefined structure in stdio.h. If the file is successfully opened then fopen returns a pointer to file; otherwise if it is unable to open a file then it returns NULL value. fgetc function returns a character, which is read from the file and fclose function closes the file.

Opening a file means bringing file from secondary storage (hard disk) to RAM so as to perform operations on it. The file must be present in the directory in which the executable file of this code is present. The code is as follows:

#include<stdio.h>

#include<stdlib.h>

main()

{

   char ch, file_name[25];

   FILE *fp;

   printf("Enter the name of file you wish to see ");

   gets(file_name);

   fp = fopen(file_name,"r"); // read mode

   if( fp == NULL )

   {

      perror("Error while opening the file.\n");

      exit(EXIT_FAILURE);

   }

   printf("The contents of %s file are :- \n\n", file_name);

   while( ( ch = fgetc(fp) ) != EOF ) //EOF denotes End-of-File

         printf("%c",ch);

   fclose(fp);

   return 0;

}

Example 2: Programme to copy a file.

This programme copies a file. Firstly, you will specify the file name with proper path, to copy and then you will enter the name of target file. Also, you must specify the extension of the file. The source file is opened in read mode ("r") and target file in write mode ("w").

#include <stdio.h>
#include <stdlib.h>
main()
{
   char ch, source_file[20], target_file[20];
   FILE *source, *target;
   printf("Enter name of file to copy\n");
   gets(source_file);
   source = fopen(source_file, "r");
   if( source == NULL )
   {
      printf("Press any key to exit...\n");
      exit(EXIT_FAILURE);
   }
   printf("Enter name of target file\n");
   gets(target_file);
   target = fopen(target_file, "w");
   if( target == NULL )
   {
      fclose(source);
      printf("Press any key to exit...\n");
      exit(EXIT_FAILURE);
   }
   while( ( ch = fgetc(source) ) != EOF )
      fputc(ch, target);
   printf("File copied successfully.\n");
   fclose(source);
   fclose(target);
   return 0;
}

Example 3: Programme to delete a file.

This ‘C’ programme deletes a file, which is entered by the user; the file to be deleted should be present in the directory in which the executable file of this programme is present. Extension of the file should also be entered. Note that deleted file does not go to recycle bin, remove macro is used to delete the file. If there is an error in deleting the file then the error will be displayed using perror function.

#include<stdio.h>
main()
{
   int status;
   char file_name[25];
   printf("Enter the name of file you wish to delete\n");
   gets(file_name);
   status = remove(file_name);
   if( status == 0 )
      printf("%s file deleted successfully.\n",file_name);
   else
   {
      printf("Unable to delete the file\n");
      perror("Error");
   }
   return 0;
}

Example 4: Programme that writes results into an output file.

#include <stdio.h>

void main()

{

FILE *fp = fopen("D:\\f_read1.txt","w");

int i;

for(i = 0;i < 5; i++)

   fprintf(fp,"i=%d\n", i);

fclose(fp);

}

Output

i=0

i=1

i=2

i=3

i=4

Eample 5: Programme to read an array of ten integers from the console and to write the entire array into a file.

#include<stdio.h>

int main()

   FILE *p;

   int i,a[10];

   if((p=fopen("E:\\myfile.txt","wb"))==NULL)

   {

      printf("\nUnable to open file myfile.dat");

      exit(1);

   } 

   printf("\nEnter ten values, one value on each line\n");

   for(i=0;i<10;i++)

      scanf("%d",&a[i]);

   for(i=0;i<10;i++)

      fprintf(p," %d ", a[i]);

  

   fclose(p); 

   return 0;

}

Output:

Enter ten values, one value on each line

11

21

34

54

23

78

37

81

27

61

Contents of output file: myfile.txt

11  21  34  54  23  78  37  81  27  61