So far, we have dealt with programs involving variables, arrays, structures and unions, which are used for manipulating information resident in the main memory (RAM) of the computer. Information kept in the RAM is temporary in nature and is also limited in size - limited by the capacity of your computer's RAM. In order to build a practical application in C it therefore becomes essential that we have some means of storing our program data permanently. Such a storage is done in the form of files which can be stored in the backup media - such as disk drive or magnetic tape drive. Data stored in files can then be retrieved by the C program as and when needed.
C allows you to store data in files as plain text files or as binary files. In either case, a file essentially represents a stream or sequence of bytes. This sequence of bytes can be meaningfully read and used/displayed by a C program. It can also be manipulated, i.e. changed as per requirement of a particular application. In the next series of articles on C we will learn how to take advantage of C's file handling facilities to build more meaningful applications.
C provides a wide spectrum of standard library functions to allow you to implement data transfer between main memory of the computer (RAM) and external storage devices - such as terminal, printer, disk drive and tape drive. Such external storage devices are all treated as files and appropriate functions are called to perform read and write operations on those files. In fact, C treats all devices as files and using suitable library functions your C program can read from and write to various devices as if you were reading from and writing to files.
So far when running your C program, you were feeding in data from your keyboard and viewing the C program's output on your monitor. Also any error message were displayed on your monitor.
Essentially, your C program was reading data from the keyboard (the standard input device - stdin), as if the keyboard device was a file and writing results on to the monitor (the standard output device - stdout) as if the monitor device was a file.
Once you understand the concept of file handling in C, you will be able to expand your knowledge to read streams of data coming in from any external device connected to a computer on which your C program is running. For instance, you may have a temperature sensor connected to an industrial furnace which would be reading the furnace temperature at 30 secs interval and dumping the read data as a steam of bytes to one of your computer ports to which the sensor is connected at the other end. You can then write a C program to open the port for reading, read the data coming into the port and store it in a file. This data (stored in file) can subsequently be read by yet another C program to display the furnace's temperature profile in the form of a graph. Such is the versatility of C that it is widely used for developing such practical applications.
To maintain a uniform access method for different types of devices, C supports the concept of buffer, which is a data structure that provides necessary logical interface to the external files. Hence, when working with stream-oriented files, the first step is to establish a buffer area, where data can be temporarily stored while being transferred between the computer system's RAM and a disk file/external device.
The buffer area is established by the following statement:
FILE *fp; /* fp is a file pointer */
The FILE (all capitals) is a structure whose declaration is included in the stdio.h header file. Hence any reference to FILE inside a program, requires the following statement.
#include <stdio.h>
The typedef struct FILE is declared in stdio.h as follows:
typedef struct { unsigned char * _ptr ; /* pointer to next char */ int _cnt; /* total character in buffer */ unsigned char *_base; /* pointer to logical buffer */ char flag; /* mode file opened in */ char _file; /* file descriptor */ } FILE;
Thus, the declaration FILE *fp;
means that the file pointer fp, points to a structure of type FILE, that contains information about the file, such as the buffer location, the current character position in the buffer, a flag indicating the mode in which file is opened, and a file descriptor. The members in the structure FILE receive values only if the file is opened successfully using fopen function.
The fopen() function is a standard library function that is used to open/create a file and associate an I/O stream with it. This function takes two arguments. The first argument is a string containing name of the file to be opened - it is essentially the full path to the file to be opened. When only file name is provided, it is assumed that the file resides in the same directory as your C program. The second argument is the mode in which the file is to be opened. Depending upon the mode in which you open the file, you will be restricted in the types of operations you can perform on the file, viz. read, write, append or rewrite.
fp = fopen(<filepath>, <mode>);
The call to fopen(), if successful, establishes a connection between file pointer and the external file. If a file cannot be opened, fopen returns NULL value to the file pointer.
The table below lists the various modes in which a file can be opened:
MODE | MEANING |
---|---|
r | Opens a text file in Read only mode. The stream is positioned at the beginning of the file. If the file with the given filepath does not exist, the file opening operation in this mode will fail. |
w | Opens or Creates a text file in Write only mode. If a file with the given filepath exists, its content will be destroyed - so essentially a new file is created. The stream is positioned at the beginning of the file. |
a | Opens a text file in Append mode, i.e. for writing at the end of file. An existing file can be opened in this mode to append more data to it. If a file with the given filepath does not exist, it will create a new file to write into it. The stream is positioned at the end of the file. |
r+ | Opens a text file in Update mode (read & write). The file will be opened in a mode so that the C program can read and update the stored data. The stream is positioned at the beginning of the file. Error occurs if the file does not exist. |
w+ | Opens a text file in Read & Write mode. It always creates a new file destroying a file having same name if exists on the disk. The stream is positioned at the beginning of the file. |
a+ | Opens a text file in Read & Append mode. If the file exists, it will be opened with the stream positioned at the beginning of the file for reading. However, when writing, it always writes (appends) data to the end of the file. If the file does not exist, a new file is created. |
When handling non-text files, viz. binary files, i.e. files in which data is stored in binary form or data is to be stored in binary form, the above modes will respectively become - rb, wb, ab, rb+, wb+, ab+.
The fopen() function allocates buffer and assigns the address of the same to the file pointer (fp) to enable carry out input-output operations on the file. It is always desirable to free the file pointer once the file operation is over and the pointer is no longer needed, since every operating system puts some restrictions on the number of files that can be opened simultaneously.
Closing of a file or in other words releasing the buffer that establishes connection to the external file/device, is performed by the standard library function fclose(). If an already opened file needs to be processed in a different mode it is always a better practice, to close the file and then reopen it in the new mode. The syntax of fclose() is as shown below:
fclose(fp);
Here is an example code snippet to give you an overview of the file handling program structure in C.
#include <stdio.h> main() { FILE *fp; fp = fopen("dummy.ext", "w"); if(fp == NULL) printf("Error the file cannot be opened \n"); else { /* perform operations on the file */ fclose(fp); } }
Here are a couple of programs that you can run to familiarize yourself with the paradigm of file handling in C.
/* A simple C program to accept text from user and store it in a file ------------------------------------------------------------------ Function getc(stdin) gets one character from keyboard and assigns it to variable ch stdin is a file pointer associated with the standard input device, viz. keyboard */ #include <stdio.h> main() { FILE *fp; char ch; puts("Enter text for storing in file1.txt."); puts("Terminate with CTRL-Z or CTRL-D, followed by <ENTER> Key"); puts("--------------------------------------------------------\n"); fp = fopen("file1.txt", "w"); if(fp == NULL) puts("Error!! Unable to create file1.txt."); else { while((ch = getc(stdin)) != EOF) { putc(ch,fp); //writes the character to file1.txt } fclose(fp); } }
/* Program to read and display the contents of a text file ------------------------------------------------------- */ #include <stdio.h> main() { FILE *fp; char ch; puts("Displaying the contents of file1.txt"); puts("------------------------------------\n"); fp = fopen("file1.txt", "r"); if(fp == NULL) puts("Error!! Unable to open file1.txt."); else { while((ch = fgetc(fp)) != EOF) printf("%c",ch); fclose(fp); } }
Data Input and Output functions in C
File Handling in C - Part 2 of 7
File Handling in C - Part 3 of 7
File Handling in C - Part 4 of 7
File Handling in C - Part 5 of 7
How to move your Email accounts from one hosting provider to another without losing any mails?
How to resolve the issue of receiving same email message multiple times when using Outlook?
Self Referential Data Structure in C - create a singly linked list
Mosquito Demystified - interesting facts about mosquitoes
Elements of the C Language - Identifiers, Keywords, Data types and Data objects
How to pass Structure as a parameter to a function in C?
Rajeev Kumar is the primary author of How2Lab. He is a B.Tech. from IIT Kanpur with several years of experience in IT education and Software development. He has taught a wide spectrum of people including fresh young talents, students of premier engineering colleges & management institutes, and IT professionals.
Rajeev has founded Computer Solutions & Web Services Worldwide. He has hands-on experience of building variety of websites and business applications, that include - SaaS based erp & e-commerce systems, and cloud deployed operations management software for health-care, manufacturing and other industries.