The fprintf and fscanf functions perform input and output
operations in much the same way as printf and scanf.
fprintf()
Syntax: fprintf(fptr,"control string",arguments);
FILE *fptr;
The filepointer specifies the file to be used while the control string
contains output specifications for the items in the arguments. The arguments may
include variables, constants and strings. For example:
fprintf(fptr,"%s %d %f",name,age,salary);
Here name is an array variable of type char, age is of type int and salary is of
type float.
fscanf()
Syntax: fscanf(fptr,"control string",arguments);
This statement would cause the reading of the arguments from the file
specified by the filepointer fptr according to the specifications contained in
the control string. Example:
fscanf(fptr,"%s %d %f",name,&age,&salary);
Like scanf, fscanf also returns the number of items read successfully. When the
end of file is reached it returns EOF.
/* Program that illustrates the use of fprintf() and fscanf() functions
*/
#include
main()
{
FILE *fp;
char item<10>,filename<10>;
int i,num,qty;
float price,value;
printf("\nEnter the filename :");
scanf("%s",filename);
fp=fopen(filename,"w");
printf("\nEnter the data\n");
printf("Item name Number Price Quantity\n");
for(i=0;i<2;i++)
{
fscanf(stdin,"%s %d %f %d",item,#,&price,&qty);
fprintf(fp,"%s %d %f %d",item,num,price,qty);
}
fclose(fp);
fp=fopen(filename,"r");
printf("\nItem name Number Price Quantity\n");
for(i=0;i<2;i++)
{
fscanf(fp,"%s %d %f %d",item,#,&price,&qty);
fprintf(stdout,"%s %d %f %d",item,num,price,qty);
}
fclose(fp);
}
Enter the filename : Inventory
Enter the data :
Item name Number Price Quantity
A 15 10.50 10
B 20 50.00 2
Output
Item name Number Price Quantity
A 15 10.50 10
B 20 50.00 2
Here the file name Inventory is supplied through the keyboard. Data is read
using the function fscanf from the file stdin, where stdin
refers to the terminal, and is then written to the file that is being pointed to
by the file pointer fp which in this case is Inventory. After closing the file
Inventory it is again reopened for reading. The data from the file are written
to the file stdout, where stdout refers to the monitor. As I’ve
mentioned before the monitor and keyboard are treated as files.
Random access to files
So far we’ve discussed functions related to files that allow reading and
writing into files in a sequential manner, but there may occur situations where
we need to access only particular data in a file. Such random accessing of files
can be achieved with the help of functions like fseek(), ftell() and
rewind()
that are available in the I/O library. Let’s take a look at each of these
functions:
ftell()
This function takes a filepointer and returns a number of type long that
corresponds to the current position. This function is useful in saving the
current position of the file, which can in turn be used later in the program. It
takes the following form:
n=ftell(fptr);
n would give the relative offset in bytes of the current position. This means
that n bytes have already been read (or written).
rewind(fptr);
n=ftell(fptr);
rewind() takes a file pointer and resets the position to the start of the
file. Therefore in the above statement n would contain the value 0 as the file
pointer is set to the beginning of the file by the function rewind(). One point
to be kept in mind is that the first byte in the file is numbered as 0, second
as 1 and so on. This function helps us in reading a file more than once without
having to close and reopen the file. Remember that whenever a file is opened for
I/O operations the rewind() function is executed implicitly.
fseek()
This function is used to move the file position to a desired location within the
file and takes the following form.
fseek(fptr,offset,position)
fptr is a pointer to the file concerned, offset is a number or variable of
type long and position is a number of type int. The offset specifies the number
of bytes to be moved from the location specified by the position. The position
can take one of the following three values:
If value =0 it indicates the beginning of file
If value =1 it indicates the current position
If value =0 it indicates the end of file
The offset may be positive, meaning move forwards or negative meaning move
backwards.
fseek(fp,0L,0); go to the beginning of file
fseek(fp,0L,1); stay at the current position
fseek(fp,0L,0); go to the end of file past the last character of the file.
fseek(fp,m,0); Move to (m+1)th byte in the file
fseek(fp,m,1); Go forward by m bytes
fseek(fp,-m,1); Go backward by m bytes from the current position
fseek(fp,-m,2); Go backward by m bytes from the end.
When the operation is successful, fseek returns zero. If we attempt to move
the file pointer beyond the file boundaries, an error occurs and fseek returns
—1. It is good practice to check whether an error has occurred or not, before
proceeding further.
Managing files
Now let’s move on to managing files in C. A file is another structured
datatype similar to an array. The characteristics of files are:
- File contents are stored in a permanent storage medium like disk.
- File data can be of different datatypes.
- Files can be arbitrary and of unlimited size whereas the size of an array
is limited and has to be declared earlier.
So far, we’ve been using the scanf and printf functions to read and write
data. These are console oriented I/O functions and work fine as long as the data
is small. However, in cases that involve large volumes of data console oriented
I/O operations pose two problems:
- It becomes cumbersome and time consuming to handle large volumes of data
through terminals. - The entire data is lost when either the program is terminated or the
computer is turned off.
Hence, it becomes necessary to have a more flexible approach where data can be
stored on the disk and read whenever necessary without destroying the data.
Hence the use of files to store data. A file is a place on the disk where a
group of related data is stored. In C, the
different I/O devices like keyboard and monitor are treated as files. The
keyboard acts as an input file and the monitor as an output file. C supports
several functions that have the ability to perform basic file operations like
opening, closing, reading, writing and naming a file.
Defining and opening a file
If we want to store data in a file in the secondary memory, we must specify
certain things about the file to the operating system. They include:
- Filename
- Data structure
- Purpose
Filename: can be made of two parts, a primary name and an optional
period with the extension. For example: trial.data, prog.c etc.
Data structure: of a file is defined as FILE in the library of
standard I/O function definitions. Therefore, all files should be declared as
type FILE before they are used. FILE is a defined datatype.
Purpose: when a file is opened we must specify the purpose i.e. what we
want to do with the file, for example whether we want to read data from the file
or write data to the file.
This is the format for declaring and opening a file:
FILE *fp;
fp=fopen("filename","mode");
The first statement declares that variable fp is a pointer to the datatype FILE
and the second statement opens the file named filename and assigns an
identifier to the FILE type pointer fp. This pointer contains all
information about the file and is subsequently used as a communication link
between the system and the program. The ‘mode’ in the second statement
specifies the purpose of opening the file and can be one of the following:
r   -  Open the file in the read mode only but
the file must already exist;
w -  Open the file in the write mode only, if the file
already exists the contents are overwritten. If it
      doesn’t
exist then a new file is opened for writing;
a  - Open the file in the append mode i.e. for adding data
at the end of file. If the file doesn’t exist
      a file
is created for writing. In this mode existing data is not overwritten.
r+Â - Opens an existing file for reading and writing (the file must
exist).
w+ - Opens an empty file for reading and writing. If the file exists the
contents will be destroyed.
a+Â - The write operation results in appending of the data and existing
data will not be overwritten.
Note: both filename and mode are specified as strings and should be enclosed
in double quotation marks.
Consider the following statements:
 FILE *p1, *p2;
 p1=fopen("emp","r");
 p2=fopen("results","w");
Here, the file emp is opened for reading and results is opened for writing. If
the emp file doesn’t exist, an error will occur. In case the file results
already exists, it’s contents are deleted and the file is opened as a new
file.
A file must be closed as soon as all operations on it have been completed.
This ensures that all outstanding information associated with the file is
flushed out from the buffers and all links to the file are broken. It also
prevents accidental misuse of the file. In case there is a limitation on the
number of files that can be kept open simultaneously, closing any unwanted files
might help open the required files. Another instance where we would have to
close a file is when we want to reopen the same file in a different mode. Other
than these reasons, it's considered good programming practice to close
unwanted files. This is how we close a file:
fclose(filepointer);
This closes the file associated with the FILE pointer ‘filepointer’.
Example:
FILE *p1, *p2;
p1=fopen("Input","w");
p2=fopen("Output","r");
………………
………………
fclose(p1);
fclose(p2);
This program opens two files and closes them after all operations on them are
completed. Once a file is closed, its file pointer can be reused with another
file. All files are automatically closed whenever that program is terminated.