A file is nothing but a collection of records and each line of the data is recorded in the file. The record is a group of related data items. All data items related to students, employees, customers, etc. are nothing but records. In other words, file is a collection of numbers, symbols and texts placed onto the secondary devices like hard disk, pen drive and compact disk. Files are stored permanently onto the disk, and one can access them for further monitoring/processing if needed. In the next few paragraphs or sections, we will learn how files can be read and modified as per requirements.
A file can be considered as a stream of characters, spaces, tabs etc. Also it can be a set of records that can be accessed through a set of library functions. These functions are available in stdio.h.
The reading and writing of data is done with streams. The streams are designed to allow the user to access files efficiently. A stream is a file and using physical device like keyboard information is stored in the file. Printer and monitor are used to display the stream. The FILE object uses these devices.
The FILE object contains all the information about a stream like current position, pointer to any buffer, error and end of file (EOF). Using this information of object, C program uses pointer, which is returned from the stream function fopen(). A function fopen() is used for opening a file.
There are two types of files.
The following operations can be performed on files in C.
Most of the compilers support file handing functions. Few file-handling functions that are available in standard library are listed in the Table 13.1. The library functions supported by ANSI compilers are very exhaustive and hence all functions are not provided. One should check the ANSI C library functions before using them.
TABLE 13.1 File functions
Function | Operation |
---|---|
fopen() | Creates a new file for read/write operation |
fclose() | Closes a file associated with file pointer |
closeall() | Closes all files opened with fopen() |
fgetc() | Reads the character from current pointer position and advances the pointer to next character |
getc() | Same as fgetc() |
fprintf() | Writes all types of data values to the file |
fscanf() | Read all types of data values from a file |
putc() | Writes character one by one to a file |
fputc() | Same as putc() |
gets() | Reads string from the file |
puts() | Writes string to the file |
putw() | Writes an integer to the file |
getw() | Reads an integer from the file |
fread() | Reads the structured data written by fwrite() function |
fwrite() | Writes block of structured data to the file |
fseek() | Sets the pointer position anywhere in the file |
feof() | Detects the end of the file |
ferror() | Reports error occurred while read/write operations |
perror() | Prints compiler's error messages along with user de..ined messages |
ftell() | Returns the current pointer position |
rewind() | Sets the record pointer at the beginning of the file |
unlink() | Removes the specified file from the disk |
rename() | Changes the name of the file |
A file has to be opened before read and write operations. Opening of a file creates a link between the operating system and the file functions. The name of the file and its mode of operation are to be indicated to the operating system. This important task is carried out by the structure FILE that is defined in stdio.h header file. So, this file must be included.
When a request is made to the operating system for opening a file, it does so by granting the request. If request is granted, the operating system points to the structure FILE. In case the request is not granted, it returns NULL. That is why the following declaration before opening of the file is to be made.
FILE *fp
where fp is file pointer.
Each file that we open has its own FILE structure. The information in the file may be its current size and its location in the memory. The only one function to open a file is fopen().
Syntax for opening a file:
FILE *fp;
fp=fopen("data.txt","r");
Here, fp is a pointer variable that contains address of the structure FILE that has been defined in the header file stdio.h. It is necessary to write FILE in upper case. The function fopen() will open a file data.txt in read mode. The C compiler reads the contents of the file because it finds the read mode ("r"). Here, "r" is a string and not a character. Hence, it is enclosed with double quotes and not with single quotes.
The fopen() performs four important tasks:
Syntax:
fp=fopen("data.txt","w");
Here, data.txt is the file name and "w" is the mode.
Syntax:
fp=fopen("data.txt","r");
if(fp= =NULL)
printf("File does not exist");
OR
if(fp=(fopen("data.txt","r"))= =NULL)
printf("File does not exist");
Here, data.txt is opened for reading only. If the file does not exist, the fopen() returns NULL to file pointer fp. Using the NULL value of fp with if statement, we can prompt the user for failure of fopen() function.
This mode opens a pre-existing file for appending data. The data appending process starts at the end of the opened file. The file pointer points to the last character of the file. If the file does not exist, then new file is opened, i.e. if the file does not exist, then the mode of "a" is same as "w". Due to some or other reasons, if the file is not opened, in such a case NULL is returned. File opening may be impossible due to insufficient space in the disk, etc. Syntax for opening a file with append mode is as follows.
Syntax:
fp=fopen("data.txt","a");
Here, if data.txt file already exists, it will be opened. Otherwise, a new file will be opened with the same name.
This mode is used for file search operation in the disk. In case the file is found, its contents are destroyed. If the file does not find, a new file is created. Returns NULL, if failed to open the file. In this file mode, new contents can be written and thereafter programmer can read them.
Example:
fp=fopen("data.txt", "w+");
In the above example, data.txt file is open for reading and writing operations.
Example:
fp=fopen("data.txt","a+");
Here, data.txt is opened and records are added at the end of the file without affecting the previous contents.
(a+): If file does not exist, a new file is created. Write operation is performed first and the contents are read thereafter. Before reading character, the pointer is set to begin the file using rewind().
This mode is used for both reading and writing. We can read and write the record in the file. If the file does not exist, the compiler returns NULL to the file pointer. It can be written as follows.
Example:
fp=fopen("data.dat","r+");
if(fp= =NULL)
printf("File not found");
In the above example, data.dat is opened for read and write operation. If fopen() failed to open the file, it returns NULL. The if statement checks the value of file pointer fp, and if it contains NULL, a message is printed and program terminates.
When numerical data is to be transferred to disk from RAM, the data occupies more memory space on disk. For example, a number 234567 needs 3 bytes memory space in RAM, and when transferred to the disk, it requires 6 bytes memory space. For each numerical digit, one byte space is needed. Hence, total requirement of memory space for the number 234567 would be 6 bytes. Thus, text mode is inefficient for storing large amount of numerical data because space occupation by it is large. Only solution to this inefficient memory use is to open a file in binary mode, which takes lesser space than text mode. Few binary modes are described below.
Example:
fp=fopen("data.dat","wb");
Here, data.dat file is opened in binary mode for writing.
Example:
fp=fopen("data.dat","rb");
Here, data.dat file is opened in binary mode for reading.
Example:
fp=fopen("data.dat","ab");
Here, data.dat file is opened in append mode.
Example:
fp=fopen("data.dat","r+b");
Here, the file data.dat is opened for reading and writing in binary mode.
Example:
fp=fopen("data.dat","w+b");
Here, the file data.dat is created for reading and writing in binary mode.
Example:
fp=fopen("data.dat","a+b");
Here, the file data.dat is opened in append mode and data can be written at the end of the file.
Once the file is opened using fopen(), its contents are loaded into the memory (partly or wholly). The pointer points to the very first character of the file. The fgetc() function is used to read the contents of the file. The syntax for fgetc() is as follows:
ch=fgetc(fp);
where fgetc() reads the character from current pointer position and advances the pointer position so that the next character is pointed. The variable ‘ch’ contains the character read by fgetc(). There are also other functions to read the contents of the file, which are explained in the coming pages.
The file that is opened from the fopen() should be closed after the work is over, i.e. we need to close the file after reading and writing operations. In other words, the file must be closed after operations. Also, whenever a opened file needs to be reopened in another mode, in such a case also the opened file must be closed first. Closing the file enables to wash out all its contents from the RAM buffer, and further the link is disconnected from the file.
Example:
The function to close a file is
fclose(fp);
This statement closes the file associated with file pointer fp. This function closes one file at a time. In order to close all files, the following function syntax is used:
fcloseall();
This function closes all the opened files and returns the number of files that have been closed. It does not require any argument.
The format of fprintf() is as follows:
fprintf(fp,"control string",text);
where fp is file pointer associated with an opened file in write mode. The text can be variables, constants or strings.
This function reads characters, strings, integers, floats, etc. from the file pointed by file pointer. This is also a formatted function. The syntax of this function is as follows.
fscanf(fp,"control string",text);
With this statement, reading operations from the designated file is done.
This function reads a single character from the opened file and moves the file pointer. It returns EOF, if end of the file is reached.
For example in the statement c=getc(f) ;, a character is read from the file whose file pointer is ‘f’. A program is illustrated under 13.E(1) based on this function.
This function is used to write a single character into a file. If an error occurs, it returns EOF.
For example, in the statement putc(c,fp);, a character contained in character variable ‘c’ is written in the file whose file pointer is fp.
This function is similar to getc() function. It also reads a character and increments the file pointer position. If any error or end of file is reached, it returns EOF.
This function writes the character to the file shown by the file pointer, and also increments the file pointer.
Syntax:
fputc(c,fp);
where fp is the file pointer and ‘c’ is a variable written to the file pointed by file pointer.
This function reads string from a file pointed by file pointer. It also copies the string to a memory location referenced by an array.
This function is useful when we want to write a string into the opened file.
This function is used to write an integer value to the file pointed by file pointer. This function deals with integer data only.
This function returns the integer value from a file and increments the file pointer. This function deals with integer data only.
The fseek() can be used to access the part of the file. The file pointer can be moved to any position in a file. It positions the file pointer on the stream. The format of fseek() is as follows.
fseek(filepointer,offset,position);
Thus, three arguments are to be passed through this function. They are
Table 13.2 displays the various values of location of file pointer.
TABLE 13.2 Locations of file pointer
Integer Value | Constant | Location in the File |
---|---|---|
0 | SEEK_SET | Beginning of the file |
1 | SEEK_CUR | Current position of the file pointer |
2 | SEEK_END | End of the file |
Example:
fseek(fp,10,0); or fseek(fp,10,SEEK_SET);
The file pointer is repositioned in the forward direction by 10 bytes.
While performing read or write operation, few times we do not get result successfully. The reason may be that the attempt of reading or writing operation may not be correct. The provision must be provided for searching the error while read/write operations are carried out.
The C language provides standard library function ferror(). This function is used for detecting any error that might occur during read/write operation of a file. It returns a ‘0’ while the attempt is successful, otherwise non-zero in case of failure.
ferror() : The ferror() is used to find out error when file read/write operation is carried out.
perror() : It is a standard library function which prints the error messages specified by the compiler.
Text files can be copied from one file to the other or in many files, whereas binary files such as .EXE if attempted to open in text mode, unexpectedly process of getting characters would stop. This is because whenever ASCII value 26 is observed copying work stops due to EOF(). Another approach to copy such binary files is with low-level disk I/O.
In the low-level disk I/O operations, data cannot be written as character by character or with sequence of characters as it is carried in the high-level disk I/O operations. In the low-level disk I/O operations, buffers are used to carry the read and write operations.
Buffer plays an important role in the low-level disk I/O program. The programmer needs to declare the appropriate buffer size. The low-level disk I/O operations are more efficient and quick than the high-level disk I/O operations.
Opening a file: To open a file or files, open() function is used. This function is defined in io.h. The syntax of open() is given below.
Syntax:
int open(const char *f_name, int access, unsigned mode);
In the low-level operation, a number is assigned to the file and the number is used to refer the file. If open() returns –1, it means that the file could not be opened, otherwise the file is successfully opened.
Table 13.3 describes the file opening modes in the low-level disk I/O operations.
TABLE 13.3 File opening modes
Mode | Meaning |
---|---|
O_APPEND | Open a file in append mode |
O_WRONLY | Opens a file for writing only |
O_RDONLY | Opens a file for writing only |
O_RDWR | Opens a file for read/write operations |
O_BINARY | Opens a file in binary mode |
O_CREAT | Creates a new file for writing |
O_EXCL | When used with O_CREAT, if the file exists, it is not overwritten |
O_TEXT | Creates a text file |
When O_CREAT flag is used, it also requires one of the arguments described in Table 13.4 to verify the read/write status of the file. These arguments are called as permission argument. The programmer need to #include the header file stat.h and types.h along with fcntl.h.
TABLE 13.4 Permission argument
Mode | Meaning |
---|---|
S_IWRITE | Writing to the file allowed |
S_IREAD | Reading from the file allowed |
Writing a file: The write() function is used to write() data into the file. This function is defined in io.h. The syntax of write() function is as given below.
Syntax:
int write(int handle, void *buf, unsigned nbyte);
Returns the number of bytes written or –1 if an error occurs.
Reading a file: The read() function reads a file. The syntax of read() function is as given below.
Syntax:
int read(int handle, void *buf, unsigned len);
Upon successful end, it returns an integer specifying the number of bytes placed in the buffer; if the file was opened in text mode, read does not count carriage returns or Ctrl-Z characters in the number of bytes read. On error, it returns –1 and sets errno.
Closing a file: The close () function closes the file. This function is defined in io.h. The syntax of close() is as given below.
Syntax:
int _close(int handle);
int close(int handle);
Upon successful finish, close() and _close() return 0; otherwise, they return –1 and set errno.
An executable program that performs a specific task for operating system is called as command. The commands are issued from the prompt of operating system. Some arguments are to be associated with the commands, and hence these arguments are called as command line arguments. These associated arguments are passed to the program.
In C language, every program starts with a main() function and that it marks the beginning of the program. We have not provided any arguments so far in the main() function. Here, we can make arguments in the main like other functions. The main() function can receive two arguments and they are: (i) argc and (ii) argv. The information contained in the command line is passed on to the program through these arguments when the main() is called up by the system.
Example:
Copy file1 file2.
Here, file1 and file2 are arguments and copy is a command. The first argument is always an executable program followed by associated arguments. If you do not specify argument, the first program name itself is an argument but the program will not run properly and will flag an error.
13.A Fill in the blanks
13.B True or false
13.C Match the following correct pairs given in Group A with Group B
13.D Select the appropriate option from the multiple choices given below
13.E What will be the output/s of the following program/s?
#include <stdio.h>
#include <conio.h>
#include <process.h>
void main()
{
FILE *f;
char c;
clrscr();
printf("Contents of file before appending: ");
f=fopen("data.txt","r");
while(!feof(f))
{
c=fgetc(f);
printf("%c",c);
}
f=fopen("data.txt","a");
if(f= =NULL)
{
printf("File can not appended");
exit(0);
}
printf(" Enter string to append:");
while(c!='.')
{
c=getche();
fputc(c,f);
}
fclose(f);
printf(" Contents of file After appending: ");
f=fopen("data.txt","r");
while(!feof(f))
{
c=fgetc(f);
printf("%c",c);
}
}
Explanation: Pre-existing file data.txt is read first that contains ab. The data appending process starts at the end of the file. The file pointer points to the last character of the file. Append some information say "cd.". As soon as .(dot) is entered, exit operation takes place in the program and one can see the output.
#include <stdio.h>
#include <conio.h>
#include <process.h>
void main()
{
FILE *f;
char c=' ';
clrscr();
f=fopen("data","w+");
if(f= =NULL)
{
printf("Can not open file");
exit(1);
}
printf("Write data & to stop press '.':");
while(c!='.')
{
c=getche();
fputc(c,f);
}
rewind(f);
printf(" Contents read:");
while(!feof(f))
printf("%c",getc(f));
}
Explanation: Pre-existing file data is read with w+ mode first that contains some information. With the same mode we can delete old information and enter new information.
#include <stdio.h>
#include <conio.h>
#include <process.h>
void main()
{
FILE *f;
char c=' ';
clrscr();
f=fopen("data","a+");
if(f= =NULL)
{
printf("Can not open file");
exit(1);
}
printf("Write data & to stop press '.':");
while(c!='.')
{
c=getche();
fputc(c,f);
}
rewind(f);
printf(" Contents read:");
while(!feof(f))
printf("%c",getc(f));
}
Explanation: Pre-existing file data is read with a+ mode first that contains some information. With the same mode we can add new information and old and new information can be seen on the screen.
#include <stdio.h>
#include <conio.h>
#include <process.h>
void main()
{
FILE *f;
char c=' ';
clrscr();
f=fopen("data","wb");
if(f= =NULL)
{
printf("Can not open file");
exit(1);
}
printf("Write data & to stop press '.':");
while(c!='.')
{
c=getche();
fputc(c,f);
}
fclose(f);
f=fopen("data","rb");
printf(" Contents read:");
while(!feof(f))
printf("%c",getc(f));
}
Explanation: A file data is opened in wb mode first and information "Wonderful gift of life" is invoked through the keyboard. With the rb mode, we can read the same information.
#include <stdio.h>
#include <conio.h>
void main()
{
FILE *fp ;
char c ;
clrscr();
fp=fopen("lines.txt","w");
if(fp= =NULL)
return;
else
{
while((c=getche())!='*'),
fputc(c,fp);
}
fclose(fp);
}
#include <stdio.h>
#include <conio.h>
void main()
{
FILE *fp ;
char ch ;
fp=fopen("lines.txt","r");
fseek(fp,8,SEEK_SET);
ch=fgetc(fp);
clrscr();
while(!feof(fp))
{
printf("%c ",ch);
printf("%d",ftell(fp));
ch=fgetc(fp);
}
fclose(fp);
}
13.F Find the bug/s in the following program/s
#include <stdio.h>
#include <conio.h>
#include <process.h>
void main()
{
FILE *fp;
char c=' ';
clrscr();
fp=fopen("data.txt","w");
if(fp= =NULL)
{
printf("Cannot read file");
exit(0);
}
printf("Write data & to stop press.: ");
while(c!='.')
{
c=getche();
fputc(c,fp);
}
printf(" Contents Read:");
fp=fopen("data.txt","r");
while(!feof(fp))
printf("%c",getc(fp));
}
#include <stdio.h>
#include <conio.h>
#include <process.h>
void main()
{
FILE *fp ;
char c=' ';
clrscr();
fp=fopen("data.txt","w");
if(fp= =NULL)
{
printf("Cannot read file");
exit(0);
}
printf("Write data & to stop press.: ");
while(c!='.')
{
c=getche();
fputc(c,fp);
}
printf(" Contents Read:");
fp=fopen("data.txt","r");
while(!feof(fp))
printf("%c",getc(fp));
}
#include <stdio.h>
#include <conio.h>
void main()
{
FILE *fp ;
char text[30];
clrscr();
fp=fopen("text.txt","w");
clrscr();
puts(" Enter Text Here ");
gets(text);
fprintf("%s",text);
}
#include <stdio.h>
#include <conio.h>
void main()
{
FILE *fp ;
char c ;
clrscr();
fp=fopen("text.txt","r");
if(fp= =NULL)
{
printf(" cannot open file");
}
while((c=getc(fp)) !=EOF)
printf("%c",c);
fclose(fp);
}
#include <stdio.h>
#include <conio.h>
void main()
{
FILE *fr ;
Char c,file[]="text.txt";
Fr=fopen(file,"w");
clrscr();
while(feof(fr))
{
c=fgetc(fr);
if(ferror(fr))
{
perror(file);
exit(0);
}
else
printf("%c",c);
}
fclose(fr);
}
#include <stdio.h>
#include <conio.h>
void main()
{
char buff[10];
clrscr();
setbuf(stdout,buff);
printf("This Book is very good");
fflush(stdout);
}
#include <stdio.h>
#include <conio.h>
void main(int argc, char argv[])
{
int x;
clrscr();
printf(" Total Number of arguments are %d ",argc);
for(x=0;x<argc;x++)
printf("%s",argv[x]);
}
13.G Attempt the following programming exercises
13.A Fill in the blanks
13.B True or false
1. T | 2. T | 3. F | 4. F | 5. T |
6. T | 7. T | 8. F | 9. T | 10. T |
11. F | 12. T | 13. F | 14. T | 15. T |
16. F | 17. T | 18. T | 19. F |
13.C Match the following correct pairs given in Group A with Group B
13.D Select the appropriate option from the multiple choices given below
13.E What will be the output/s of the following program/s?
13.F Find the bug/s in the following program/s
3.135.234.192