File Handling in "C"
In Computer, when we run programs, they use memory
(RAM) to store the variables, which are temporary. Memory is volatile and its
content will be in memory till the program is running, once the program get
terminated, then values stored in parameter also erased. If we need data again
then we need to use keyboard input. So this will be valid for small data, but
for large data it’s not possible to enter data again and again when you require
it and another way to get the values may be generate the values pragmatically.
But both of the ways are very difficult to implement.
So we need to store data on disk, which we can retrieve whenever we require. So
here we are going to discuss how to store data on disk and perform various
input and output operations.
Note: Data which we store on disk is always stored
in form of binary data. Binary data which we store on disk may be varies from
OS.
DATA ORGANIZATION
All DATA on the Disk store in the Binary form. How this
binary data is stored on the Disk varies from one OS to another.
However, this doesn’t affect programmer. He has to use only the library
functions written for the particular OS to be able to perform input/output. It
is compiler vendor’s responsibility to correctly implement these library
functions by taking the help of OS.
File:- A file
represents a sequence of byte on the disk where a group of related data is
stored. File is created for permanent storage of data. We use a structure
pointer of file type to declare a file.
e.g. File *file;
File is named location of stream of bits. It may be stored at
single place or different places but it represents a single stream.
There are 2 types of
files:-
Ø Text Files
Ø 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.
Binary files:-
A binary file is no
different to a text file. It is a collection of bytes. In C Programming
Language 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 Programming
Language 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 Programming
Language, 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.
Advantage of File:-
It will contain the data even after
program exit. Normally we use variable or array to store data, but data is lost
after program exit. Variables and arrays are non-permanent storage medium
whereas file is permanent storage medium.
Stream:-
Stream is not a hardware it is linear
queue which connect file to program and passes block of data in both direction
.So it is independent of devices which we are using. We can also define
stream as source of data. This source can be
(a) A file
(b) Hard disk or CD, DVD etc.
(c) I/O devices etc.
In c programming language there are two
type of stream.
(a) Text streams
(b) Binary streams
Buffer :- Buffer is a technique
which reduces number of I/O call.
Through file handling,
one can perform operations like create, modify, delete etc on system files.
File Handling:-
C
language basically provides two mechanisms to handle the files:
- Low-Level File Handling
- High-Level File Handling
Low-Level
File Handling:-
The
low-level file handling mechanism requires the secondary storage devices to
directly fetch/put a specific number of bytes for each read/write request. It
provides no formatting facilities (i.e. data-types are irrelevant) as we are
dealing directly with the bytes. In this approach the files are referred
through integer numbers termed as file descriptors. As we handle the data in
binary format (prescribing exactly how many bytes to read or write) this
approach baffles a novice programmer.
High-Level File Handling:-
C
provides a wrapper around the low-level file handling mechanism which uses
buffers to communicate with secondary storage devices. A program’s read/write
requests are transferred through a buffer. As this enables data management
through available data-types, a programmer can perceive it in a normal sense.
As
the high-level file handling approach simplifies involved process considerably,
we will follow the same further. It is also referred as buffered input/output
(I/O).
High-Level File Handling
in C Language:-
The
involved buffers in high-level file handling are used through an abstraction
termed as “streams”. The streams provide a
portable way of writing/reading data to/from a file. A stream is considered as
a file or a physical device (e.g.printer
or monitor). The involved input/output (I/O) through a stream is buffered (i.e.
a fixed chunk is read from or written to a file via some temporary storage
area, the buffer). A pointer to a stream is used to manipulate the stream. It
is termed as a file pointer and it actually points to involved buffer.
File Pointer:-
There
exists an internal C data structure, FILE, which represents all streams. FILE is
a structure containing the information about a file or text stream needed to
perform input or output operations on it. It includes the following fields:
- a file descriptor
- the current stream
position
- an end-of-file indicator
- an error indicator
- a pointer to the
stream's buffer, if applicable
It
is declared in the header file “stdio.h”. We simply need to refer to the FILE
structure in C programs when performing I/O with streams. The declaration of
the FILE structure is as follows:
typedef struct{
short level;
unsigned flags;
char fd;
unsigned char hold;
short bsize;
unsigned char *buffer, *curp;
unsigned istemp;
short token;
}FILE;
A
file pointer is declared as a pointer to this FILE structure.
FILE
*fp; /* fp is declared as a FILE pointer */
The
high-level file handling provides a set of functions involving file pointers to
perform various operations on files. Generally all the functions in this set are
prefixed with “f”.
File
I/O Stream:-
Ø All I/O is
done with streams.
Ø Stream is
nothing but sequence of byte of data.
Ø A sequence
of byte flowing into stream is called Input Stream.
Ø A sequence
of byte flowing out of stream is called Output Stream.
Ø Use of stream
make I/O machine independent.
Predefined Streams:-
stdin
|
Standard
Input
|
Stdout
|
Standard
Output
|
Stderr
|
Standard
Error
|
Standard
Input Stream device:-
Ø stdin
stands for standard input
Ø Keyboard is
input stream device.
Ø Standard
input is data(often text) going in to a program.
Ø The program
requests data transfer by use of read operation.
Ø Not all
program require input.
Standard
Input Stream device:-
Ø stdout
stands for standard output
Ø Screen(monitor)
is output stream device.
Ø Standard
output is data(often text) going out from a program.
Ø The program
sends data to output device by using write operation.
Difference
b/w Standard Input & Standard Output
device
Point
|
Standard Input Stream Device
|
Standard Output Stream Device
|
Stands for
|
Standard Input
|
Standard Output
|
Example
|
Keyboard
|
Screen(Monitor)
|
Data Flow
|
Data(often text) going into program
|
Data(often text) going out from the program
|
Operation
|
Read Operation
|
Write Operation
|
Some
important Summary:-
Point
|
Input Stream
|
Output Stream
|
Standard Device 1
|
Keyboard
|
Screen
|
Standard Device 2
|
Scanner
|
Printer
|
IO Function
|
scanf & gets
|
printf & puts
|
IO Operation
|
Read
|
Write
|
Data
|
Data goes from Stream
|
Data comes into Stream
|
Text
File Format:-
Ø Text File
is also calld “Flat File”.
Ø Text File
is simple sequence of ASCII characters.
Ø Each line
is characterized by EOL character.
Text File Formats:-
Ø Text file
have .txt Extension.
Ø Files with
.txt extension can easily be read or opened by any program that reads text and,
for that reason, are considered universal(or platform independent).
File Operations:-
There are different
operations that we can carry out on a file.
These operations are
general operations which we need to work on files.
a)
Creation of a new file
b)
Opening an existing file
c)
Reading from a file
d)
Writing to a file
e)
Append content to file
f)
We can assign name to file
g)
We can rename to file name
h)
We can position to particular byte in
the file
i)
We can check end of the line in file
j)
Can find size of the file
k)
We can delete the file
l)
We can return result of last file
input/output operation from the file
m) Copy a file to another file
n)
Closing a file
Functions for file handling:-
There are many functions in C library
to open, read, write, search and close file.
Function
|
Syntax
|
Example
|
fopen - Open file
|
FILE * fopen(char *
filename, char * mode)
Filename – string filename with
path
Mode – mode of opening
r read only
w write only
a append file
+ read and write (r+/w+/a+)
Return value – FILE pointer on success
NULL on failure
|
FILE * infile ;
Infile = fopen(“a.txt”,”r”);
FILE *outfile = fopen(“b.txt”,”w”);
if(infile==NULL || outfile==NULL)
{
printf(“error”);
}
|
fclose – close the open file
|
fclose(FILE *fptr)
fptr – FILE * of the open file
Returns void
|
fclose(infile);
|
fgetc – read one char from file
|
int fgetc(FILE
*fptr)
fptr – FILE * of the open file
returns – character read
-1 on eof or error
|
while( (ch=fgetc())!=-1)
putchar(ch);
//display content of file
//on screen
|
fputc – write one character to the file
|
int fputc(int
ch,FILE *fptr)
ch – character to write
fptr – open file pointer
returns character written
EOF if there is error
|
for(ch=’A’;ch<=’Z’;ch++)
fputc(ch,fptr);
|
fscanf –
reads data from file
|
int fscanf(FILE
*ptr,char * fmt,…)
ptr – FILE pointer
fmt – format specifier for
variables to be read
Returns – number of values read
successfully
|
fscanf(infile, “%d
%d”,&n1,&n2);
|
fprintf – write data into file
|
int
fprintf(FILE *ptr,char * fmt,…)
ptr – FILE pointer
fmt – format specifier for
variables to be read
Returns – number of characters
printed or negative number on error
|
fprintf(outfile,“Value is
%d\n”,n1);
|
fread – read from binary file
|
int fread( void
*buffer, size_t size, size_t num, FILE *ptr )
buffer – stores the value read
size – size of the buffer
num – number of blocks to be read
ptr – file pointer
Returns – number of values read
|
Char *str = malloc(50);
fread(str,50,1,infile);
|
fwrite – write to a binary file
|
int fwrite( void *buffer,
size_t size, size_t num, FILE *ptr )
buffer – stores the value read
size – size of the buffer
num – number of blocks to be read
ptr – file pointer
Returns – number of values written
|
for(i=0;i<10;i++)
fwrite(&i,sizeof(i),1,outfile);
char a[]=”end”;
fwrite(a,strlen(a)+1,1,outfile);
|
fseek – move the file pointer by given offset
|
int
fseek(FILE*ptr,long offset,int whence)
ptr – file pointer
offset – offset in bytes from third parameter
whence – SEEK_SET – from beginning of file
SEEK_CUR – from current position
SEEK_END – from end of file
Returns – zero on success
Non-zero on failure
|
if(fseek(infile,4L,SEEK_SET)==0)
{
char
ch=fgetc(infile);
printf(“The fourth char of the file is %c\n”,ch);
}
|
ftell – get the position of file pointer
|
int ftell(FILE *ptr)
ptr – FILE pointer
Returns – position of file pointer
-1 on error
|
FILE *ptr =
fopen(b[1],"r");
fseek(ptr,0L,SEEK_END);
int size_of_file =
ftell(ptr);
|
rewind – moves the file pointer to the beginning of the
file
|
void rewind(FILE
*ptr)
ptr – FILE pointer
|
rewind(infile);
int n = fscanf(infile,”%d”,&n);
|
feof – detects end-of-file marker in a file.
|
|
|
Opening
File:-
Concept:- Before we read (or write) information from (to
file) on a disk, we must open a file in particular mode. To open a file we use
fopen() function. fopen() is a high level IO function. There are many high
level IO function we use in file handling.
fopen():-
It opens a file and associates a stream
with it. It returns a file pointer that identifies the stream in subsequent
operations.
Header
File:
- stdio.h
Syntax: - FILE *fopen(const
char *filename, const char *mode);
Arguments:-
- filename: File that the function open
- mode: Defines the mode of the opened file
or
Syntax:-
FILE *fp;
fp= fopen(“filename”,”mode”);
|
FILE = it’s a data
structure type. Its defined in standard I/O function definitions
fp = this is a file
pointer of type FILE data structure.
fopen = High
level IO function
filename = valid
filename which you want to open
mode = (read,
write, append)
How to open file?
1.
fopen( ) opens a stream.
2.
fopen( ) opens a file &
associate a stream with it.
3.
Function returns a pointer that
identifies the stream in subsequent operations means fopen() will return the
address of the structure that contains information needed for subsequent I/O on
the file being opened(i.e. file pointer).
e.g. here fopen() will open “file.txt” in the read mode.
fp=fopen(“file.txt”,”r”);
Before storing data on secondary storage, firstly we must
specify following things:-
1. File Name
2. Data
Structure
3. Purpose/Mode
4. Very first
task in file handling is to open a file
File
Name:-
1. File name
consist of 2 fields.
2. First field
is name field & second
field is extension field.
3. Extension
field is optional.
4. Both file
name & extensions are separated by period or dot.
Data
Structure:-
1. Data
Structure of file is defined as FILE in the library of standard I/O functions.
2. In short we
have to declare the pointer variable of type FILE.
Opening
Mode:-
We can open file in different modes such as reading mode,
writing mode, appending mode depending
on purpose of file.
Following
are the different opening modes of File:-
MODE
|
DESCRIPTION
|
r
|
Opens an text file for reading mode
If file is opened successfuly fopen() loads it in to memory & sets up a pointer which points to
first character in it. If the file can’t be opened, fopen() returns NULL.
|
w
|
Opens or create a text file for
writing mode
If file exists, its content are
overwritten . If the file doesn’t exist, a new file is created, It returns
NULL if unable to open a file.
|
a
|
Opens a text file in append mode
means adding new contents at the end of file
If file is opened successfuly fopen() loads it in to memory & sets up a pointer which points to
last character in it. If the file doesn’t exist, a new file is created, It
returns NULL if unable to open a file.
|
r+
|
Opens an text file in both reading
& writing mode
If file is opened successfuly fopen()
loads it in to memory & sets up a
pointer which points to first character in it. If the file can’t be opened,
fopen() returns NULL.
|
w+
|
Opens an text file in both reading
& writing mode
If file exists, its content are overwritten . If the file doesn’t
exist, a new file is created, It returns NULL if unable to open a file.
|
a+
|
Opens an text file in both reading
& writing mode but can’t modify existing content
If file is opened successfuly fopen()
loads it in to memory & sets up a
pointer which points to first character in it. If the file doesn’t exist, a
new file is created, It returns NULL if unable to open a file.
|
rb
|
Opens an binary file for reading
mode
|
wb
|
Opens or create a binary file for
writing mode
|
ab
|
Opens a binary file in append mode
|
rb+
|
Opens an binary file in both reading
& writing mode
|
wb+
|
Opens an binary file in both reading
& writing mode
|
ab+
|
Opens an binary file in both reading
& writing mode
|
In fact fopen() performs three important tasks when you open the
file in “r” mode:
a.
Firstly it searches on the disk the file to be
opened.
b.
Then it loads the file from the disk into a place
in memory called buffer.
c.
It sets up a character pointer that points to the
first character of the buffer.
Why do we need a buffer at all?
Imagine how efficient it would be to actually access the disk every time we
want to read a character from it. Every time we read something from a disk, it
takes some time for the disk drive to position the read/write head correctly.
On a floppy disk system, the driver motor has to actually start rotating the
disk from a standstill position every time the disk is accessed. If this were
to be done for every character we read from the disk, it would take a long time
to complete the reading operation. This is where a buffer comes in . It would
be more sensible to read the contents of the file into the buffer while opening
the file and then read the file character by character from the buffer rather than from the disk.
fopen() returns this address of this structure, which is
collected in the structure pointer called fp.We
have declared fp as
File *fp;
Example
1 of opening the file:-
#include<stdio.h>
int main()
{
FILE *fp;
char ch;
fp = fopen("INPUT.txt","r") // Open file in Read mode
fclose(fp); // Close File after Reading
return(0);
}
Example
2 of opening the file:-
#include<stdio.h>
void main()
{
FILE *fp;
char ch;
fp = fopen("INPUT.txt","r"); // Open file in Read mode
while(1)
{
ch = fgetc(fp); // Read a Character
if(ch == EOF ) // Check for End of File
break ;
printf("%c",ch);
}
fclose(fp); // Close File after Reading
}
Closing a File:-
Whenever we open a file in read or write mode then we perform
appropriate operations on file and when file is no longer needed then we close
the file. The only argument it[fclose()
function] accepts is the file pointer.
FILE close will flush out all the entries from buffer.
Important:-
Ø After performing all operations, File is no longer
needed.
Ø File is closed using fclose() function.
Ø All information associated with file is flushed out of
buffer.
Ø Closing file will prevent misuse of FILE.
Syntax:
fclose()
int
fclose (FILE *fp);
The fclose(
) function returns zero on
success, or EOF if there is an error in closing the
file. This function actually, flushes any data still pending in the buffer to
the file, closes the file, and releases any memory used for the file. In case of failure, if the stream is accessed further then
the behavior remains undefined. The EOF is a constant defined in the header file stdio.h.
Return
Type : fclose()
Action
|
Return Value
|
On Success
|
0
|
On Error
|
NULL
|
If a program terminates, it
automatically closes all opened files. But it is a good programming habit to
close any file once it is no longer needed. This helps in better utilization of
system resources, and is very useful when you are working on numerous files
simultaneously. Some operating systems place a limit on the number of files
that can be open at any given point in time.
Input and Output
using file pointers
Writing a File
When
a file is opened for writing, it will be created if it does not already exist
and it will be reset if it does, resulting in the deletion of any data already
there. Using the w indicates that the file is assumed to be a text file.
Character Output with
File using putc() function:-
The functions putc() is
equivalent to putchar() functions,
except that these functions require an argument which is the file pointer.Function putc() writes a character to the file
identified by its second argument.
The
format of putc() function is as follows :
putc(c, out_file);
Note:-The second argument
in the putc() function must be a file opened in
either write or append mode.
Example 1
#include<stdio.h>
#include<string.h>
void writeToFile(char* fileName);
void main()
{
char fileName[20];
printf("Enter File Name
\t:");
scanf("%s",fileName);
fflush(stdin);
// Clear the buffer from memory
writeToFile(fileName);
}
void writeToFile(char* fileName)
{
FILE
*fp; // File
Pointer
char c;
fp= fopen(fileName,"w"); // Opening
file in writing mode
printf("Enter the content , Enter ctrl+Z
to exit :\n\n");
printf
(“*****************************************\n\n”);
while((c=getchar())!=EOF)
{
putc(c,fp);
// Writing Characters in file using pointer
}
fclose(fp);
// Closing File Pointer
printf
(“\n\n*****************************************\n”);
printf("%s File Written successfully\n",fileName);
}
Example 2
#include <stdio.h>
main ()
{
char in_file[30], out_file[30];
FILE *fpin, *fpout;
int c;
printf("This program copies the source file to the destination file
\n\n");
printf("Enter name of the source file :");
scanf("%30s", in_file);
printf("Enter name of the destination file :");
scanf("%30s", out_file);
if((fpin=fopen(in_file, "r")) == NULL)
printf("Error could not open source file for
reading\n");
else if ((fpout=fopen(out_file, "w")) == NULL)
printf("Error could not open destination file for
reading\n");
else
{
while((c =getc(fpin)) != EOF)
putc(c, fpout);
printf("Destination file has been copied\n");
}
}
Important Points:–
1. When we open file in write mode, automatic
a buffer area will assigned to that pointer.
2. The characters which we want to
save on file, first save in that buffer area only, once we finishes our
writing, then it will copy into that file.
3. If the buffer gets full, then it
will copy the content on disk or file and make space for new content
4. At the end of file it puts EOF
character to indicate end of file.
5. Buffer plays a important role in
writing text file or appending text.
Formatted Output with
File Pointers using fprintf() function
This
function is the parent function of printf(). The normal printf() function
writes the contents to the screen whereas fprintf() writes them to a file
identified by a stream. On success it returns the number of bytes output. On
error it will return EOF.
To
work with text output, you use fprintf , both of which are similar to their
friends printf except that you must pass the FILE
pointer as first argument.
Header File: stdio.h
Syntax: int fprintf(FILE *stream, const
char *format [, argument, …]);
Arguments:
- stream: Stream where the function output the formatted data
- format: Normal format string as that of printf() function
For
example:
FILE
*fp;
fp=fopen("c:\\test.txt",
"w");
fprintf(fp,
"Testing...\n");
Here
is the program to create a file and write some data into the file.
e.g. 1
#include <stdio.h>
int main()
{
FILE *fp;
file = fopen("file.txt","w");
/*Create a file and add text*/
fprintf(fp,"%s","This is just an example :)"); /*writes data to the file*/
fclose(fp); /*done!*/
return 0;
}
e.g. 2
#include<stdlib.h>
#include<stdio.h>
int
main()
{
FILE
*fp
=
fopen("/path/to/file/filename.txt",
"w");
if
(fp
==
NULL)
{
fprintf(stderr,
"Can't open input file!\n");
exit(1);
}
fprintf(fp,
"Whatever you want to write.\n");
fprintf(fp,
"Really, anything.\n");
fclose(fp);
return
0;
}
Formatted Output
with Strings
This is the third set of the printf families. This
is called sprintf.
sprintf
puts
formatted data into a string which must have sufficient space allocated to hold
it. This can be done by declaring it as an array of char. The data is formatted
according to a control string of the same form as that for printf.
Reading a File
If you want to read a file you
have to open it for reading in the read (r) mode. Using the r indicates
that the file is assumed to be a text file. Opening a file for reading requires
that the file already exist. If it does not exist, the file pointer will be set
to NULL and can be checked by the program.
Character
Input with Files using getc() function
Ø we use getc function to read from file. This function reads character
from current pointer location and returns character, which we can save in a
character variable and display on screen.
Ø To read using this function we need a loop which will iterate through all
characters and display on screen or perform any operation.
Ø We use while loop to iterate through the file, but before using any loop
we need a condition to break the rule.
Ø In files, usually it puts a character at end of each file, we can check
for this character and break the loop. This character has ASCII value of 26 and
we can also define it as EOF. So we can check for this variable and break the
rule.
Ø EOF is defined in stdio.h header file.
The
functions getc() is
equivalent to getchar() function,
except that this functions require an argument which is the file pointer. Function getc() reads
a single character from the file which has previously been opened using a
function like fopen().
Example
#include<stdio.h>
#include<string.h>
void readFromFile(char * fileName);
void main()
{
char
fileName[20];
printf("Enter File Name \t:");
scanf("%s",fileName);
fflush(stdin);
// Clear the buffer from memory
readFromFile(fileName);
}
void readFromFile(char* fileName)
{
FILE
*fp; // File Pointer
char c;
fp=
fopen(fileName,"r"); //
Opening file in reading mode
if(fp==NULL)
{
printf("File not found \n");
printf("Please check file Name\n");
exit();
}
printf("File Reading
:\n\n");
printf("*************************************************\n\n");
while((c=getc(fp))!=EOF)
{
printf("%c",c); //
Display Characters on screen
}
printf("\n\n***********************************************\n");
fclose(fp); // Closing
File Pointer
printf("\n\n %s File read
successfully\n",fileName);
}
Reading a file character by character
#include <stdlib.h>
#include <stdio.h>
int
main()
{
FILE
*fp
=
fopen("/path/to/file/filename.txt",
"r");
if
(fp
==
NULL)
{
fprintf(stderr,
"Can't open input file!\n");
exit(1);
}
int
ch;
while
((ch
=
fgetc(fp))
!=
EOF)
{
char
character
=
(char)
ch;
// do something with character
printf("%c",
character);
}
fclose(fp);
return
0;
}
Formatted Input with
File Pointers using fscanf() function
fscanf() is the parent function of scanf()
function. It takes input from the specified stream. It returns the number of
input fields successfully scanned, converted and stored. It returns 0 (zero)
when no field is stored or EOF when it attempts to read at end-of-file.
Header File: stdio.h
Syntax: int fscanff(FILE *stream, const
char *format [, argument, …]);
Arguments:
- stream: Stream from where the function takes the formatted data
- format: Normal format string as that of scanf() function
The function fscanf() is
similar to scanf() except
that this function operates on files and require one additional and first
argument to be a file pointer.
Reading a file word by word
#include <stdlib.h>
#include <stdio.h>
int
main()
{
FILE
*fp
=
fopen("/path/to/file/filename.txt",
"r");
if
(fp
==
NULL)
{
fprintf(stderr,
"Can't open input file!\n");
exit(1);
}
char
word[64];
// assuming no word in the file is longer than 64 characters.
while
(fscanf(fp,
"%64s",
word)
!=
EOF)
{
// do something with word
printf("%s\n",
word);
}
fclose(fp);
return
0;
}
Formatted Input
Output with Strings
This is the third set of the scanf families. This
is called sscanf.
sscanf
takes
data from a string and stores it in other variables as specified by the control
string. This is done in the same way that scanf reads input data into
variables. sscanf is very useful for converting strings into numeric v values.
Whole Line Input
and Output using File Pointers
Predictably,
equivalents to gets and puts exist called fgets and fputs. The programmer
should be careful in using them, since they are incompatible with gets and
puts. gets requires the programmer to specify the maximum number of characters
to be read. fgets and fputs retain the trailing newline character on the line
they read or write, wheras gets and puts discard the newline.
When transferring data from files to standard input / output channels, the
simplest way to avoid incompatibility with the newline is to use fgets and
fputs for files and standard channels too.
For
Example, read a line from the keyboard using
fgets(data_string, 80, stdin);
and
write a line to the screen using
fputs(data_string, stdout);
fgets() Function
fgets
library functions can be used to read the contents of the file. (It is also
possible to make use of the library function fscanf. But you have to be sure
that the file is perfectly formatted or fscanf will not handle it correctly).
Let’s take a look at an example:
#include<stdio.h>
int
main()
{
FILE
*file;
char
buf[1000];
file=fopen(input.txt,”r”);
if(!file)
return
1;
while(fgets(buf,1000,file)!=NULL)
printf(“%s”,buf);
fclose(file);
return
0;
}
Note:-The
printf statement does not have the new-line (\n) in the format string. This is
not necessary because the library function fgets adds the \n to the end of each
line it reads.
A
file “input.txt” is opened for reading using the function fopen en the mode
read (r). The library function fgets will read each line (with a maximum of
1000 characters per line.) If the end-of-file (EOF) is reached the fgets
function will return a NULL value. Each line will be printed on stdout
(normally your screen) until the EOF is reached. The file is then closed and
the program will end.
Program
to write and read data from a file
# include
<stdio.h>
# include
<conio.h>
void main()
{
char c ;
FILE *fptr1 ;
clrscr() ;
printf("Enter
the text to be stored in the file.\n") ;
printf("Use ^Z
or F6 at the end of the text and press
ENTER: \n\n") ;
fptr1 =
fopen("COURSES.DAT","w") ;
while((c = getc(stdin))
!= EOF)
fputc(c, fptr1) ;
fclose(fptr1) ;
printf("\nThe
content of the file is : \n\n") ;
fptr1 =
fopen("COURSES.DAT", "r") ;
do
{
c = fgetc(fptr1) ;
putchar(c) ;
} while(c != EOF) ;
fclose(fptr1) ;
getch() ;
}
Example of
fprintf() & fscanf() Function
#include
<stdio.h>
main
()
{
FILE *fp;
float total;
fp = fopen("data.txt",
"w+");
if (fp == NULL) {
printf("data.txt does not exist,
please check!\n");
exit (1);
}
fprintf(fp, 100);
fscanf(fp, "%f", &total);
fclose(fp);
printf("Value of total is %f\n",
total);
}
Binary stream input and output
The functions fread() and fwrite() are a somwhat complex file
handling functions used for reading or writing chunks of data containing NULL
characters ('\0') terminating strings.
The declarations for each are similar:
size_t
fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE
*a_file);
size_t
fwrite(const void *ptr, size_t size_of_elements, size_t number_of_elements,
FILE *a_file);
Both of these functions deal with blocks of memories -
usually arrays. Because they accept pointers, you can also use these functions
with other data structures; you can even write structs to a file or a read
struct into memory.
Let's look at one function to see how the notation works.
fread takes four arguments. Don't be confused by the
declaration of a void *ptr; void means that it is a pointer(that can be used
for any type variable) to the buffer that is used to reading/writing the data.
The first argument is the name of the array or the address of the structure you
want to write to the file. The second argument is the size of each element of
the array; it is in bytes. For example, if you have an array of characters, you
would want to read it in one byte chunks, so size_of_elements is one. You can
use the sizeof operator to get the size of the various datatypes; for example,
if you have a variable int x; you can get the size of x with sizeof(x);. This
usage works even for structs or arrays. E.g., if you have a variable of a
struct type with the name a_struct, you can use sizeof(a_struct) to find out how
much memory it is taking up.
e.g.,
sizeof(int);
The third argument is simply how many elements you want to
read or write; for example, if you pass a 100 element array, you want to read
no more than 100 elements, so you pass in 100.
The final argument is simply the file pointer we've been
using. When fread is used, after being passed an array, fread will read from
the file until it has filled the array, and it will return the number of
elements actually read. If the file, for example, is only 30 bytes, but you try
to read 100 bytes, it will return that it read 30 bytes. To check to ensure the
end of file was reached, use the feof function, which accepts a FILE pointer
and returns true if the end of the file has been reached.
fwrite is similar in usage, except instead of reading into
the memory you write from memory into a file.
For example,
FILE *fp;
fp=fopen("c:\\test.bin", "wb");
char x[10]="ABCDEFGHIJ";
fwrite(x, sizeof(x[0]), sizeof(x)/sizeof(x[0]), fp);
Function fread() reads it as a stream of bytes and advances
the file pointer by the number of bytes read. If it encounters an error or
end-of-file, it returns a zero, you have to use feof() or ferror() to
distinguish between these two.
Let us rewrite program using fread() and fwrite() functions .
Program
#include <stdio.h>
#define MAX_SIZE 1024
main ()
{
FILE *fp, *gp;
char buf[MAX_SIZE];
int i, total = 0;
if ((fp =
fopen("data1.txt", "r") ) == NULL)
printf("Error
in data1.txt file \n");
else if
((gp=fopen("data2.txt", "w")) == NULL)
printf("Error
in data2.txt file \n");
else
{
while(i=fread(buf,
1, MAX_SIZE, fp))
{
fwrite(buf, 1,
MAX_SIZE, gp);
total +=i;
}
printf("Total
is %d\n", total);
}
fclose(fp);
fclose(gp);
}
Appending(a) a File
When a file is opened for appending, it
will be created if it does not already exist and it will be initially empty. If
it does exist, the data input point will be positioned at the end of the
present data so that any new data will be added to any data that already exists
in the file. Using the a indicates that the file is assumed to be a text file.
We open
the file in append mode by following way
fp = fopen(fileName,”a”);
fp =
File pointer
filename
= name of file in which we need to append text
#include<stdio.h>
#include<string.h>
void
appendToFile(char* fileName);
void
main()
{
char fileName[20];
printf("Enter File Name
\t:");
scanf("%s",fileName);
fflush(stdin); // Clear the buffer from memory
appendToFile(fileName);
}
void
appendToFile(char* fileName)
{
FILE *fp; // File Pointer
char c;
fp=
fopen(fileName,"a"); //
Opening file in appending mode
printf("Enter content which
you want to append :\n\n");
printf("******************************************\n\n");
while((c=getchar())!=EOF)
{
putc(c,fp); // saving Characters in file
}
fclose(fp); // Closing File Pointer
printf("\n\n*************************************\n\n");
printf("\n\n %s
: Content saved
successfully\n",fileName);
}
fseek()
This function repositions the file
pointer of a stream. It sets the file pointer associated with a stream to a new
position. fseek() returns a 0 (zero) on success, otherwise it returns a
non-zero value on error.
Header File: stdio.h
Syntax: int fseek(FILE *stream, long offset, int whence);
Arguments:
- stream: Stream whose file pointer fseek sets
- offset: tells the amount of bytes to seek.
or
Difference in bytes
between whence (a file pointer position) and new position.
- whence: tells from where the seek of
‘offset’ number of bytes is to be done. The available values for whence
are:-
Table 3 lists the three SEEK modes for “whence”
argument:
SEEK Mode
|
File Location
|
SEEK_SET
|
Seeks from beginning of file
|
SEEK_CUR
|
Seeks from current position
|
SEEK_END
|
Seeks from end of file
|
EOF is a character which indicates the end of a file. It
is returned by read commands of the getc and scanf families when they try to
read beyond the end of a file.
When
you are reading from a file it is useful to be able to check whether or not you
have reached the end, without just failing to read. The function feof can be used to find out if you
have hit the end :
if
( feof (input_file ) ) printf ( "BANG!\n" ) ;
Copy
a file to another file
1.
To copy a file to another file, we need two file pointers.
2.
File which we need to copy should be open in read mode (file A), as we
don’t need to perform any write operation on that file. Another file we need to
open in write mode(file B).
3.
We get character by character from file A and put that in file B.
Example :-
#include<stdio.h>
#include<string.h>
void copyFile(char* oldFileName, char*
newFileName);
void main()
{
char oldFileName[20],newFileName[20];
printf("Enter the File Name
which we need to copy \t:");
scanf("%s",oldFileName);
fflush(stdin); // Clear the buffer from memory
printf("Enter the new File Name
\t:");
scanf("%s",newFileName);
fflush(stdin); // Clear the buffer from memory
copyFile(oldFileName,newFileName);
}
void copyFile(char* oldFileName, char*
newFileName)
{
FILE *oldP,*newP; // File Pointer
char c;
oldP=
fopen(oldFileName,"r"); //
Opening file in reading mode
newP=
fopen(newFileName,"w");
if(oldP==NULL)
{
printf("File not found
\n");
printf("Please check
file Name\n");
exit();
}
while((c=getc(oldP))!=EOF)
{
putc(c,newP); // Display Characters on screen
}
fclose(oldP); // Closing File Pointer
fclose(newP);
printf("\n\n File copied successfully\n");
}
Function int fstat (char *, struct stat *) store the
information of open file in form of structure struct stat Structure struct stat has been
defined in sys\stat.h as
struct stat
{
short st_dev, st_ino;
short st_mode, st_nlink;
int st_uid, st_gid;
short st_rdev;
long st_size, st_atime;
long st_mtime,
st_ctime;
};
Here
(a)st_dev: It describe file has
stored in which drive of your computer ,it returns a number.
(b)st_mode: It
describes various modes of file like file is read only, write only,
folder, character file etc.
(c)st_size: It tells the size of
file in byte.
(d)st_ctime:It tells last data
of modification of the file in date format.
Note: 65 is ASCII value of A .So after
adding status.st_dev with 65 it will return appropriate drvie
name as in your computer.
There are some macro has been defined in sys\stat.h
Name Meaning
S_IFMT File type mask
S_IFDIR Directory
S_IFIFO FIFO special
S_IFCHR Character special
S_IFBLK Block special
S_IFREG Regular file
S_IREAD Owner can read
S_IWRITE Owner can write
S_IEXEC Owner can execute
So masking or bit wise and operation
between status.st_mode and S_IREAD return true you have read permission and so
on.
WRITE A C PROGRAM
TO FIND SIZE OF A FILE
#include <time.h>
#include <sys\stat.h>
#include <stdio.h>
void main()
{
struct stat status;
FILE *fp;
fp=fopen("test.txt","r");
fstat(fileno(fp),&status);
clrscr();
printf("Size of file :
%d",status.st_size);
printf("Drive name :
%c",65+status.st_dev);
getch();
}
Write a c program to find out the
last date of modification
#include <time.h>
#include <sys\stat.h>
#include <stdio.h>
void main(){
struct stat status;
FILE *fp;
fp=fopen("test.txt","r");
fstat(fileno(fp),&status);
clrscr();
printf("Last date of
modification : %s",ctime(&status.st_ctime));
getch();
}
Write a c program to know
read/write permission of given file
#include "time.h"
#include "sys\stat.h"
#include "stdio.h"
void main(){
struct stat
status;
FILE *fp;
stat("test.txt",&status);
clrscr();
if (status.st_mode
& S_IREAD)
printf("You have read permission.\n");
if (status.st_mode
& S_IWRITE)
printf("You have write permission.");
getch();
}
What
is difference between file opening mode r+ and w+ in c?
Both r+ and w+ we can read ,write on
file but r+ does not truncate (delete) the content of
file as well it doesn’t create a new file if such file
doesn’t exists while in w+ truncate the content of file as well as
create a new file if such file doesn’t exists.