Files in C
Files in C
• A file is a collection of data stored on a secondary storage device like hard disk.
• A file is basically used because real life applications involve large amounts of data and in such
situations the console oriented I/O operations pose two major problems:
• First, it becomes cumbersome and time consuming to handle huge amount of data through
terminals.
• Second, when doing I/O using terminal, the entire data is lost when either the program is
terminated or computer is turned off. Therefore, it becomes necessary to store data on a
permanent storage (the disks) and read whenever necessary, without destroying the data.
STREAMS IN C
• In C, the standard streams are termed as pre-connected input and output channels between a text
terminal and the program (when it begins execution). Therefore, stream is a logical interface to the
devices that are connected to the computer.
• Stream is widely used as a logical interface to a file where a file can refer to a disk file, the
computer screen, keyboard, etc. Although files may differ in the form and capabilities, all streams
are the same.
• The three standard streams in C languages are- standard input (stdin), standard output (stdout)
and standard error (stderr).
• Standard input (stdin): Standard input is the stream from which the program receives its data.
The program requests transfer of data using the read operation. However, not all programs require
input. Generally, unless redirected, input for a program is expected from the keyboard.
• Standard output (stdout): Standard output is the stream where a program writes its output
data. The program requests data transfer using the write operation. However, not all programs
generate output.
• Standard error (stderr): Standard error is basically an output stream used by programs to report
error messages or diagnostics. It is a stream independent of standard output and can be redirected
separately. No doubt, the standard output and standard error can also be directed to the same
destination.
• A stream is linked to a file using an open operation and disassociated from a file using a close
operation.
• The buffer acts as an interface between the stream (which is character-oriented) and the disk
hardware (which is block oriented). When the program has to write data to the stream, it is saved
in the buffer till it is full. Then the entire contents of the buffer are written to the disk as a block.
TYPES OF FILES
• In C, the types of files used can be broadly classified into two categories- text files and binary files.
• A text file is a stream of characters that can be sequentially processed by a computer 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.
• Because text files only process characters, they can only read or write data one character at a
time.
• In a text file, each line contains zero or more characters and ends with one or more characters that
specify the end of line. Each line in a text file can have maximum of 255 characters.
BINARY FILES
• A binary file is a file which may contain any type of data, encoded in binary form for computer
storage and processing purposes. Like a text file, a binary file is a collection of bytes. Note that in C
a byte and a character are equivalent. Therefore, a binary file is also referred to as a character
stream with following two essential differences.
USING FILES IN C
• There can be a number of files on the disk. In order to access a particular file, you must specify the
name of the file that has to be used. This is accomplished by using a file pointer variable that
points to a structure FILE (defined in stdio.h). The file pointer will then be used in all subsequent
operations in the file. The syntax for declaring a file pointer is
FILE *file_pointer_name;
FILE *fp;
Then, fp is declared as a file pointer.An error will be generated if you use the filename to access a
file rather than the file pointer
Opening a File
• A file must be first opened before data can be read from it or written to it. In order to open a file
and associate it with a stream, the fopen() function is used. The prototype of fopen() can be given
as:
• Using the above prototype, the file whose pathname is the string pointed to by file_name is opened
in the mode specified using the mode. If successful, fopen() returns a pointer-to-structure and if it
fails, it returns NULL.
MODE DESCRIPTION
Open a text file for reading. If the stream (file) does not exist then an error will be
R
reported.
Open a text file for writing. If the stream does not exist then it is created otherwise if
W
the file already exists, then its contents would be deleted
A Append to a text file. if the file does not exist, it is created.
Open a binary file for reading. B indicates binary. By default this will be a sequential file
Rb
in Media 4 format
Wb Open a binary file for writing
Ab Append to a binary file
Open a text file for both reading and writing. The stream will be positioned at the
r+ beginning of the file. When you specify "r+", you indicate that you want to read the file
before you write to it. Thus the file must already exist.
Open a text file for both reading and writing. The stream will be created if it does not
w+
exist, and will be truncated if it exist.
Open a text file for both reading and writing. The stream will be positioned at the end of
a+
the file content.
r+b/ rb+ Open a binary file for read/write
w+b/wb+ Create a binary file for read/write
a+b/ab+ Append a binary file for read/write
The fopen() can fail to open the specified file under certain conditions that are listed below:
FILE *fp;
fp = fopen("Student.DAT", "r");
if(fp==NULL)
{
printf("\n The file could not be opened");
exit(1);
}
OR
char filename[30];
FILE *fp;
gets(filename);
fp = fopen(filename, "r+");
if(fp==NULL)
{
printf("\n The file could not be opened");
exit(1);
}
CLOSING A FILE USING FCLOSE()
• To close an open file, the fclose() function is used which disconnects a file pointer from a file. After
the fclose() has disconnected the file pointer from the file, the pointer can be used to access a
different file or the same file but in a different mode.
• The fclose() function not only closes the file but also flushed all the buffers that are maintained for
that file
• If you do not close a file after using it, the system closes it automatically when the program exits.
However, since there is a limit on the number of files which can be open simultaneously; the
programmer must close a file when it has been used. The prototype of the fclose() function can be
given as,
• Here, fp is a file pointer which points to the file that has to be closed. The function returns an
integer value which indicates whether the fclose() was successful or not. A zero is returned if the
function was successful; and a non-zero value is returned if an error occurred.
• fscanf()
• fgets()
• fgetc()
• fread()
fscanf()
• The fscanf() is used to read formatted data from the stream. The syntax of the fscanf() can be
given as,
int fscanf(FILE *stream, const char *format,…);
• The fscanf() is used to read data from the stream and store them according to the parameter
format into the locations pointed by the additional arguments.
#include<stdio.h>
main()
{ FILE *fp;
Char name[80];
int roll_no;
fp = fopen("Student.DAT", "r");
if(fp==NULL)
{ printf("\n The file could not be opened");
exit(1);
}
printf("\n Enter the name and roll number of the student : ");
fscanf(stdin, "%s %d", name, &roll_no); /* read from keyboard */
printf(“\n NAME : %s \t ROLL NUMBER = %d", name, roll_no);
// READ FROM FILE- Student.DAT
fscanf(fp, "%s %d", name, &roll_no);
printf(“\n NAME : %s \t ROLL NUMBER = %d", name, roll_no);
fclose(fp);
}
fgets()
• fgets() stands for file get string. The fgets() function is used to get a string from a stream. The
syntax of fgets() can be given as:
• The fgets() function reads at most one less than the number of characters specified by size (gets
size - 1 characters) from the given stream and stores them in the string str. The fgets() terminates
as soon as it encounters either a newline character or end-of-file or any other error. However, if a
newline character is encountered it is retained. When all the characters are read without any error,
a '\0' character is appended to end the string.
FILE *fp;
char str[80];
fp = fopen("Student.DAT", "r");
if(fp==NULL)
{
printf("\n The file could not be opened");
exit(1);
}
while (fgets(str, 80, fp) != NULL)
printf("\n %s", str);
printf("\n\n File Read. Now closing the file");
fclose(fp);
fgetc()
• The fgetc() function returns the next character from stream, or EOF if the end of file is reached or
if there is an error. The syntax of fgetc() can be given as
• fgetc returns the character read as an int or return EOF to indicate an error or end of file.
• fgetc() reads a single character from the current position of a file (file associated with stream).
After reading the character, the function increments the associated file pointer (if defined) to point
to the next character. However, if the stream has already reached the end of file, the end-of-file
indicator for the stream is set.
FILE *fp;
char str[80];
int i, ch;
fp = fopen("Program.C", "r");
if(fp==NULL)
{ printf("\n The file could not be opened");
exit(1);
}
// Read 79 characters and store them in str
ch = fgetc(fp);
for( i=0; (i < 79 ) && ( feof( fp ) == 0 ); i++ )
{ str[i] = (char)ch;
ch = fgetc( stream );
}
str[i] = '\0';
printf( "\n %s", str);
fclose(fp);
fread()
• The fread() function is used to read data from a file. Its syntax can be given as
int fread( void *str, size_t size, size_t num, FILE *stream );
• The function fread() reads num number of objects (where each object is size bytes) and places
them into the array pointed to by str. The data is read from the given input stream.
• Upon successful completion, fread() returns the number of bytes successfully read. The number of
objects will be less than num if a read error or end-of-file is encountered. If size or num is 0,
fread() will return 0 and the contents of str and the state of the stream remain unchanged. In case
of error, the error indicator for the stream will be set.
• The fread() function advances the file position indicator for the stream by the number of bytes
read.
FILE *fp;
char str[11];
fp = fopen("Letter.TXT", "r+");
if(fp==NULL)
{
printf("\n The file could not be opened");
exit(1);
}
fread(str, 1, 10, fp);
str[10]= '\0';
printf("\n First 9 characters of the file are : %s", str);
fclose(fp);
WRITING DATA TO FILES
• fprintf()
• fputs()
• fputc()
• fwrite()
fprintf()
• The fpritnt() is used to write formatted output to stream. Its syntax can be given as,
FILE *fp;
int i;
char name[20];
float salary;
fp = fopen("Details.TXT", "w");
if(fp==NULL)
{ printf("\n The file could not be opened");
exit(1);
}
for(i=0;i<10;i++)
{ puts("\n Enter your name : ");
gets(name);
fflush(stdin);
puts("\n Enter your salary : ");
scanf("%f", &salary);
fprintf(fp, " (%d) NAME : [%-10.10s] \t SALARY " %5.2f", i, name, salary);
}
fclose(fp);
fputs()
• The fputs() is used to write a line into a file. The syntax of fputs() can be given as
int fputs( const char *str, FILE *stream );
• The fputs() writes the string pointed to by str to the stream pointed to by stream. On successful
completion, fputs() returns 0. In case of any error, fputs() returns EOF.
#include<stdio.h>
main()
{
FILE *fp;
char feedback[100];
fp = fopen("Comments.TXT", "w");
if(fp==NULL)
{
printf("\n The file could not be opened");
exit(1);
}
printf("\n Kindly give the feedback on tyhis book : ");
gets(feedback);
fflush(stdin);
fputs(feedback, fp);
fclose(fp);
}
fputc()
#include<stdio.h>
main()
{
FILE *fp;
char feedback[100];
int i;
fp = fopen("Comments.TXT", "w");
if(fp==NULL)
{
printf("\n The file could not be opened");
exit(1);
}
printf("\n Kindly give the feedback on this book : ");
gets(feedback);
for(i=0i<feedback[i];i++)
fputc(feedback[i], fp);
fclose(fp);
}
fwrite()
The fwrite() is used to write data to a file. The syntax of fwrite can be given as,
int fwrite(const void *str, size_t size, size_t count, FILE *stream);
The fwrite() function will write, from the array pointed to by str, up to count objects of size specified by
size, to the stream pointed to by stream.
The file-position indicator for the stream (if defined) will be advanced by the number of bytes successfully
written. In case of error, the error indicator for the stream will be set.
main(void)
{ FILE *fp;
size_t count;
char str[] = "GOOD MORNING ";
fp = fopen("Welcome.txt", "wb");
if(fp==NULL)
{ printf("\n The file could not be opened");
exit(1);
}
count = fwrite(str, 1, strlen(str), fp);
printf("\n %d bytes were written to the files”, count);
fclose(fp);
}
fwrite() can be used to write characters, integers, structures, etc to a file. However, fwrite() can be used
only with files that are opened in binary mode.
while(1)
{ c = fgetc(fp); // here c is an int variable
if (c==EOF)
break;
printf("%c", c);
}
• The other way is to use the standard library function feof() which is defined in stdio.h. The feof() is
used to distinguish between two cases
• When a stream operation has reached the end of a file
• When the EOF ("end of file") error code has been returned as a generic error indicator even when
the end of the file has not been reached
• The prototype of feof() can be given as:
• Feof() returns zero (false) when the end of file has not been reached and a one (true) if the end-
of-file has been reached.
while( !feof(fp)
{ fgets(str, 80, fp);
printf("\n %s", str);
}
FUNCTIONS FOR SELECTING A RECORD RANDOMLY
fseek()
• fseek() is used to reposition a binary stream. The prototype of fseek() can be given as,
• fseek() is used to set the file position pointer for the given stream. Offset is an integer value that
gives the number of bytes to move forward or backward in the file. Offset may be positive or
negative, provided it makes sense. For example, you cannot specify a negative offset if you are
starting at the beginning of the file. The origin value should have one of the following values
(defined in stdio.h):
• SEEK_SET: to perform input or output on offset bytes from start of the file
• SEEK_CUR: to perform input or output on offset bytes from the current position in the file
• SEEK_END: to perform input or output on offset bytes from the end of the file
• SEEK_SET, SEEK_CUR and SEEk_END are defined constants with value 0, 1 and 2 respectively.
• On successful operation, fseek() returns zero and in case of failure, it returns a non-zero value. For
example, if you try to perform a seek operation on a file that is not opened in binary mode then a
non-zero value will be returned.
• fseek() can be used to move the file pointer beyond a file, but not before the beginning.
Write a program to print the records in reverse order. The file must be opened in binary mode.
Use fseek()
#include<stdio.h>
#include<conio.h>
main()
{ typedef struct employee
{ int emp_code;
char name[20];
int hra;
int da;
int ta;
};
FILE *fp;
struct employee e;
int result, i;
fp = fopen("employee.txt", "rb");
if(fp==NULL)
{ printf("\n Error opening file");
exit(1);
}
for(i=5;i>=0;i--)
{ fseek(fp, i*sizeof(e), SEEK_SET);
fread(&e, sizeof(e), 1, fp);
printf("\n EMPLOYEE CODE : %d", e.emp_code);
printf("\n Name : %s", e.name);
printf("\n HRA, TA and DA : %d %d %d", e.hra, e.ta, e.da);
}
fclose(fp);
getch();
return 0;
}
rewind()
• rewind() is used to adjust the position of file pointer so that the next I/O operation will take place
at the beginning of the file. It’s prototype can be given as
ftell()
• The ftell function is used to know the current position of file pointer. It is at this position at which
the next I/O will be performed. The syntax of the ftell() defined in stdio.h can be given as:
long ftell (FILE *stream);
• On successful, ftell() function returns the current file position (in bytes) for stream. However, in
case of error, ftell() returns -1.
• When using ftell(), error can occur either because of two reasons:
• First, using ftell() with a device that cannot store data (for example, keyboard)
• Second, when the position is larger than that can be represented in a long integer. This will usually
happen when dealing with very large files
FILE *fp;
char c;
int n;
fp=fopen("abc","w");
if(fp==NULL)
{ printf("\n Error Opening The File");
exit(1);
}
while((c=getchar())!=EOF)
putc(c,fp);
n = ftell(fp);
fclose(fp);
fp=fopen("abc","r");
if(fp==NULL)
{ printf("\n Error Opening The File");
exit(1);
}
while(ftell(fp)<n)
{ c= fgetc(fp);
printf('%c", c);
}
fclose(fp);
remove()
• The remove() as the name suggests is used to erase a file. The prototype of remove() as given in
stdio.h can be given as,
• The remove() will erase the file specified by filename. On success, the function will return zero and
in case of error, it will return a non-zero value.
• The rename() as the name suggests is used to renames a file. The prototype is:
• Here, the oldname specifies the pathname of the file to be renamed and the newname gives the
new pathname of the file.
• On success, rename() returns zero. In case of error, it will return a non-zero value will set the
errno to indicate the error.
• Command-line arguments are given after the name of a program in command-line operating
systems like DOS or Linux, and are passed in to the program from the operating system.
• The integer, argc specifies the number of arguments passed into the program from the command
line, including the name of the program.
• The array of character pointers, argv contains the list of all the arguments. argv[0] is the name of
the program, or an empty string if the name is not available. argv[1] to argv[argc – 1] specifies
the command line argument. In the C program, every element in the argv can be used as a string.