File Handling in C-language
Streams and Files
The C I/O system supplies a consistent interface to the programmer independent of the actual device being accessed. That is, the C I/O system provides a level of abstraction between the programmer and the device. This abstraction is called a stream and the actual device is called a file.
Streams
The C file system is designed to work with a wide variety of devices, including terminals, disk drives, and tape drives. Even though each device is very different, the buffered file system transform each into a logical device called stream. All streams behave similarly. Because streams are largely device independent, the same function that can write to a disk file can also be used to write ton another type of device, such as the console.
There are two types of streams as follows:
1) Text stream: A text stream is a sequence of characters. Standard C allows (but not required) a text stream to be organized into lines terminated by a newline character. However, the newline character is optional on the last line. In a text stream, certain character translations may occur as required by the host environment. For example, a newline may be converted to a carriage return/linefeed pair. Therefore there may not be a one-to-one relationship between the character that are written (or read) and those on the external device.
2) Binary stream: A binary stream is a sequence of bytes that have a one-to-one correspondence to those in the external device-that is, no character translation occur. Also, the number bytes written (or read) are the same as the number on the external device.
Files
In C/C++, a file may be anything from a disk file to a terminal or printer. You associate a stream with a specific file by performing an open operation. Once a file is open, information may be exchanged between it and your program. Here we have to remember all streams are same but all files are not.
You disassociate a file from a specific stream with a close operation. If you close a file opened for output, the contents, if any, of its associated stream are written to the external device. This process is generally referred to as flushing the stream, and guarantees that no information is accidentally left in the disk buffer. All files are closed automatically when your program terminates normally. But files are not closed when a program terminates abnormally.
Each stream is associated with a file, has a file control structure of type FILE.
The File Pointer
A file pointer is a pointer to a structure of type FILE. It points to information that defines various things about the file, including its name, status, and the current position of the file. To obtain a file pointer variable, use a statement like this:
FILE *fp;
Opening a File
The fopen( ) function opens stream for use and link a file with that stream. Then it returns the file pointer associated with the file. The fopen( ) function has the following prototype:
FILE *fopen(const char *filename, const char *mode);
where filename is a pointer to a string of characters that makeup a valid filename and may include a path specification. The string pointed to by mode determines how the file will be opened. The following table shows the legal values for mode.
Mode | Meaning |
| r | Open a text file for reading. |
| w | Create a text file for writing. |
| a | Append to a text file. |
| rb | Open a binary file for reading |
| wb | Create a binary file for writing. |
| ab | Append to a binary file. |
| r+ | Open a text file for read/write. |
| w+ | Create a text file for read/write. |
| a+ | Append or create a text file for read/write. |
| r+b / rb+ | Open a binary file for read/write. |
| w+b / wb+ | Create a binary file for read/write. |
| a+b / ab+ | Append or create a binary file for read/write. |
If, when opening a file for read only operation, the file does not exist, fopen( ) will fail. When opening a file using append mode, if the file does not exist, it will be created. Further, when a file is opened for append, all new data written to the file will be written to the end of the file. The original content will remain unchanged. When a file is opened for writing, the file does not exist, it will be created. If it does exist, the content of the original file will be destroyed and a new file created. The difference between the mode r+ and w+ is that r+ will not create a file if it does not exist; however, w+ will. Further, if the file already exists, opening it with w+ destroys its contents; opening with r+ does not.
The number of files that may be open at any one time is specified by FOPEN_MAX. this value will usually be at least 8.
Closing a File
The fclose( ) function closes the stream that was opened by a call to fopen( ). It writes any data still remaining in the disk buffer to the file and does a formal operating-system-level close on the file. Failure to close a stream invites all kind of trouble, including lost data, destroyed file, and possible intermittent error in your program. fclose( ) also frees the file control block associated with the stream, making it available for reuse. The prototype for fclose( ) function is as follows;
int fclose(FILE *fp);
where fp is the file pointer returned by the call to fopen( ). A return value of zero signifies a successful close operation. The function returns EOF if an error occurs.
There is another function fcloseall( ) which requires no argument and closes all open file at a time.
EXM 01: Write a program to check whether a file is present or not in the disk.
# include
# include
int main(void)
{
char fln[20];
FILE *fp;
clrscr();
printf("\n Give the name of the file: ");
scanf(“%s”, fln);
fp=fopen(fln,"r");
if(fp)
printf("\n The file %s is persent in the current directory",fln);
else
printf("\n The file %s is not persent in the current directory",fln);
fclose(fp);
return 0;
}
Reading and Writing a Character
There are two identical way to output a character: putc( ) (macro) and fputc( ). Prototype of putc( ):
int putc(int ch, FILE *fp);
where fp is a file pointer returned by fopen( ) and ch is the character to be output. If a putc( ) operation is successful, it returns the character written. Otherwise, it returns EOF.
Similarly there are two equivalent functions that input a character: getc( ) and fgetc( ). The prototype of getc( ):
int getc(FILE *fp);
getc( ) returns an integer, but the character is contained in the low-order byte. Unless an error occurs, the high-order byte is zero. getc( ) function returns an EOF when the end-of –file has been reached or if an error occur.
EXM 02: Write a program to create a file.
# include
# include
int main(void)
{
FILE *fp;
char fln[20],ch;
printf("\n Give the file name to create: ");
scanf("%s", fln);
fp=fopen(fln,"w");
if(!fp)
{
printf("\n File opening error...");
exit(1);
}
printf("\n Now type its content & press (ctrl+z) to terminate the file:-\n");
while((ch=getche())!=26)
putc(ch,fp);
printf("\n One file copied...");
fclose(fp);
return 0;
}
EXM 03: Write a program to read a file.
# include
# include
# include
int main(void)
{
char fln[20],ch;
FILE *fp;
clrscr();
printf("\n Give the file name to be read: ");
scanf("%s", fln);
fp=fopen(fln,"r");
if(!fp)
{
printf("\n The file cannot be opened");
exit(1);
}
printf("\n The content of the file %s :-\n ",fln);
while((ch=getc(fp))!=EOF)
putchar(ch);
getch();
return 0;
}
Using feof( )
There is a problem to deal with EOF using getc( ) function, if a file is opened for binary input, an integer value that will test equal to EOF may be read. This would cause the input routine to indicate an end-of –file condition even though the physical end of the file had not been reached. On the other hand as getc( ) returns EOF when it fails and when it reaches the end of the file. Using only the return value of getc( ), it is impossible to know which occurred. This problem can be solved by using feof( ) function, which determines when the end of file has been encountered. The feof( ) function has the following prototype:
int feof(FILE *fp);
feof( ) returns true if the end of the file has been reached; otherwise it returns zero.
EXM 04: Write a file copy program using command line argument.
# include
# include
int main(int argc, char *argv[]){
char ch;
FILE *fps, *fpt;
if(argc != 3){
printf("\n Invalid number argument......");
exit(0);
}
fps=fopen(argv[1], "r");
fpt=fopen(argv[2], "w");
if( !fps || !fpt ){
printf("\n File openning error......");
exit(0);
}
while( !feof(fps) ){
ch=getc( fps );
putc(ch, fpt);
}
printf("\n One file copied......");
return 0;
}
Try yourself:
Problem 01: Suppose a text file contains so many characters in both lower case and upper case. Now create another file where all these characters of the first one are present but all characters are in upper case. Write a program to perform the above-mentioned task.
Problem 02: Write "C" program to count the number of words in a file. Assume that a word is a sequence of letters ending with a blank, or a tab or a end of line marker or end of file or punctuation symbols such as ",", ".", "!" and "?".
fputs( ) and fgets( )
fgets( ) and fputs( ) functions read and write character strings from and to a disk file. They have the following prototypes:
int fputs(const char *str, FILE *fp);
char *fgets(char *str, int length, FILE *fp);
fputs( ) function returns EOF if an error occurs. Here in the program given below gets( ) does not store the newline character, hence a newline should be added before each string is written to the file so that the file can be read more easily.
The fgets( ) function read a string from the specified stream until either a newline character is read or length-1 character has been read. If a newline is read, it will be part of the string (unlike the gets( ) function) . The resultant string will be null terminated. The function returns str if successful and a null pointer if an error occurs.
rewind( )
The rewind( ) function resets the file position indicator to the beginning of the file specified as its argument. It has the following prototype:
void rewind(FILE *fp);
EXM 05: Write a program to accept strings from keyboard & write them to the file. At last read the accepted strings from the file & display them on the screen.
# include
# include
# include
int main(void)
{
FILE *fp;
char fln[15], str[80];
printf("\n Give the file name: ");
scanf("%s", fln);
fp=fopen(fln,"w+");
if(!fp)
{
printf("\n File opening error");
exit(1);
}
printf("\n Enter few lines of texts & press twice to terminate:-\n");
do
{
fflush(stdin);
gets(str);
strcat(str,"\n");
fputs(str,fp);
}while(str[0]!='\n');
printf("\n\t 1 File(s) copied");
printf("\n\n View the written content of the file...\n");
rewind(fp);
while(!feof(fp))
{
fgets(str,79,fp);
printf(str);
}
fclose(fp);
return 0;
}
End of Part 1 to be continued on part 2...
No comments:
Post a Comment