File I/O Operations In C Language

File I/O:

The C standard library I/O functions allow you to read and write data to both files and devices. There are no predefined file structures in C, all data being treated as a sequence of bytes. These I/O functions may be broken into two different categories : stream I/O and low-level I/O.

The stream I/O functions treat a data file as a stream of individual characters. The appropriate stream function can provide buffered, formatted or unformatted input and output of data, ranging from single characters to complicated structures. Buffering streamlines the I/O process by providing temporary storage for data which takes away the burden from the system of writing each item of data directly and instead allows the buffer to fill before causing the data to be written.

The low-level I/O system on the other hand does not perform any buffering or formatting of data --instead it makes direct use of the system's I/O capabilities to transfer usually large blocks of information.

Stream I/O:

The C I/O system provides a consistent interface to the programmer independent of the actual device being accessed. This interface is termed a stream in C and the actual device is termed a file. A device may be a disk or tape drive, the screen, printer port, etc. but this does not bother the programmer because the stream interface is designed to be largely device independent. All I/O through the keyboard and screen that we have seen so far is in fact done through special standard streams called stdin and stdout for input and output respectively. So in essence the console functions that we have used so far such as printf(), etc. are special case versions of the file functions we will now discuss.

There are two types of streams : text and binary. These streams are basically the same in that all types of data can be transferred through them however there is one important difference between them as we will see.

Text Streams:

A text stream is simply a sequence of characters. However the characters in the stream are open to translation or interpretation by the host environment. For example the newline character, ' ', will normally be converted into a carriage return/linefeed pair and ^Z will be interpreted as EOF. Thus the number of characters sent may not equal the number of characters received.

Binary Streams:

A binary stream is a sequence of data comprised of bytes that will not be interfered with so that a one-to-one relationship is maintained between data sent and data received.

Common File Functions:

  • fopen() open a stream
  • fclose() close a stream
  • putc() & fputc() write a character to a stream
  • getc() & fgetc() read a character from a stream
  • fprintf() & fscanf formatted I/O
  • fgets() & fputs() string handling
  • fseek() position the file pointer at a particular byte
  • feof() tests if EOF
fopen() open a stream
fclose() close a stream
putc()& fputc() write a character to a stream
getc()& fgetc() read a character from a stream
fprintf()& fscan formatted I/O
fgets() & fputs() string handling
fseek() position the file pointer at a particular byte
feof() tests if EOF

Opening and Closing Files:

A stream is associated with a specific file by performing an open operation. Once a file is opened information may be exchanged between it and your program. Each file that is opened has a unique file control structure of type FILE ( which is defined in along with the prototypes for all I/O functions and constants such as EOF (-1) ). A file pointer is a pointer to this FILE structure which identifies a specific file and defines various things about the file including its name, read/write status, and current position. A file pointer variable is defined as follows

FILE  *fptr ;

The fopen() function opens a stream for use and links a file with that stream returning a valid file pointer which is positioned correctly within the file if all is correct. fopen() has the following prototype

FILE *fopen( const char *filename, const char *mode );

where filename is a pointer to a string of characters which make up the name and path of the required file, and mode is a pointer to a string which specifies how the file is to be opened. The following table lists some values for mode.

r opens a text file for reading (must exist)
w opens a text file for writing (overwritten or created)
a append to a text file
rb opens a binary file for reading
wb opens a binary file for writing
ab appends to a binary file
r+ opens a text file for read/write (must exist)
w+ opens a text file for read/write
a+ append a text file for read/write
rb+ opens a binary file for read/write
wb+ opens a binary file for read/write
ab+ append a binary file for read/write

If fopen( ) cannot open "test.dat " it will a return a NULL pointer which should always be tested for as follows.

FILE *fp ;
if (  ( fp = fopen( "test.dat", "r" ) )  ==  NULL )
	puts( "Cannot open file") ;
	exit( 1) ;

This will cause the program to be exited immediately if the file cannot be opened. The fclose() function is used to disassociate a file from a stream and free the stream for use again.

fclose( fp ) ;

fclose() will automatically flush any data remaining in the data buffers to the file.

Reading & Writing Characters:

Once a file pointer has been linked to a file we can write characters to it using the fputc() function.

fputc(  ch,  fp ) ;

If successful the function returns the character written otherwise EOF. Characters may be read from a file using the fgetc() standard library function.

ch =  fgetc( fp ) ;

When EOF is reached in the file fgetc( ) returns the EOF character which informs us to stop reading as there is nothing more left in the file.

For Example :- Program to copy a file byte by byte

#include  <stdio.h>
void main()
FILE *fin, *fout ;
char dest[30], source[30], ch ;

puts( "Enter source file name" );
gets( source );
puts( "Enter destination file name" );
gets( dest ) ;

if ( ( fin = fopen( source, "rb" ) )  == NULL )        // open as binary as we don’t
	{// know what is in file
	puts( "Cannot open input file ") ;
	puts( source ) ;
	exit( 1 ) ;

if ( ( fout = fopen( dest, "wb" ) )  == NULL )
	puts( "Cannot open output file ") ;
	puts( dest ) ;
	exit( 1 ) ;

while ( ( ch = fgetc( fin ) )  !=  EOF  )
	fputc( ch , fout ) ;

fclose( fin ) ;
fclose( fout ) ;

NOTE : When any stream I/O function such as fgetc() is called the current position of the file pointer is automatically moved on by the appropriate amount, 1 character/ byte in the case of fgetc() ;

Working with strings of text:

This is quite similar to working with characters except that we use the functions fgets() and fputs() whose prototypes are as follows :-

int fputs( const char *str, FILE *fp ) ;
char *fgets( char *str, int maxlen, FILE *fp ) ;

For Example : Program to read lines of text from the keyboard, write them to a file and then read them back again.

#include <stdio.h>
void main()
char file[80], string[80] ;
FILE *fp ;

printf( "Enter file Name : " );
gets( file );

if (( fp = fopen( file, "w" ))  == NULL )//open for writing
	printf( "Cannot open file %s", file ) ;
	exit( 1 ) ;

while ( strlen ( gets( str ) ) > 0 )
	fputs( str, fp ) ;
	fputc( "\n", fp ) ;  /* must append \n for readability -- not stored by gets() */

fclose( fp ) ;

if (( fp = fopen( file, "r" ))  == NULL )//open for reading
	printf( "Cannot open file %s", file ) ;
	exit( 1 ) ;

while (fgets( str, 79, fptr )  != EOF )// read at most 79 characters
	puts( str ) ;

fclose( fp ) ;
#file_I-O_operations_in_C_language #file_I-O_operations_in_C #file_operations_in_c #File_input_output_in_c #Stream_I/O:_in_c #Text_Streams_in_c #Binary_Streams_in_c #fopen()_in_c #fclose()_in_c #putc()&__fputc()_in_c #_getc()&_fgetc()_in_c #fprintf()&_fscan__in_c #fgets()_&_fputs()_in_c #fseek()_in_c #_feof()_in_c #Opening_and_Closing_Files_in_c #Reading_&_Writing_Characters_in_c #Working_with_strings_of_text_in_c

(New page will open, for Comment)

Not yet commented...