In this tutorial, you will learn about file handling in C. You will learn to handle standard I/O in C using fprintf(), fscanf(), fread(), fwrite(), fseek() etc. with the help of examples.
We’ll be covering the following topics in this tutorial:
What is File Handling in C
The C language file handling principle used to archive the data on the disc permanently. This idea helps us to preserve our data in secondary (hard disc) memory. Both associated files are accessible in the header package stdio.h.
File handling in C are performing by calling “open,” “close,” “read” and “submit” or calling “fopen,” “fclose,” “fread,” “fwrite,” “get,” “put,” “println” and “scanf” functions of higher-levels. The operations of the higher level are specified in the C standard while the operating system defines the functions of the lower level.
The distinction is that the operations at a higher level are portable on any device. Still, the processes of the lower level allow yourself more power over the operating system-specific stuff. People expected to conform to more significant standards of operations when writing code for different operating systems.
Functions use in File Handling in C
Function | Description |
fopen() | To create a file. |
fclose() | To close an existing file. |
getc() | Read a character from a file. |
putc() | Write a character in file. |
fprintf() | To write set of data in file. |
fscanf() | To read set of data from file. |
getw() | To read an integer from a file. |
putw() | To write an integer in file. |
How file handling works
Once we compile and run a program, it gets the output, but the result isn’t saved anywhere in the framework as details.
What if we want to store the outcome for future references? After all, most tech companies compose programmes to store the results as records. By integrating file handling in C, this issue can easily be overcome. Since most computer systems use files to, store information, C offers this advantage of file handling.
Need for File Handling in C
There was a moment when the result generated when the software is compiled and output is not expected. If we wish to review the performance many times, compiling and running the same software several times is a repetitive job. It is where the files handling falls into effect. Below are some of the following explanations for file management’s popularity:
• Reusability: helps to retain the data collected after the software is run.
• Huge storage capacity: you don’t need to think about the issue of mass storage using data.
• Save time: Unique applications need a lot of user feedback. You can quickly open some aspect of the code using special commands.
• Portability: You can quickly move file material from one operating device to another without thinking about data loss.
Declaring a File Pointer
Before opening a file, you have to declare a pointer to a structure of type FILE called a file pointer. The FILE type is a structure that contains information needed for reading and writing a file. The information generally includes the operating system’s name for the file, the current character position in the file, whether the file is being read or written and so on. This structure declares within the header file stdio. h. The declaration of the file pointer made as follows,
FILE *fp; //fp is the name of the file pointer
Here fp is declared as a pointer to a structure of type FILE.
Opening a file – for creation and edit
Once the file pointer has been declared, the next step is to open an appropriate file to perform any operation. This is done using the function fopen(), specified in the header file stdio.h. To open a file as standard I/O, the syntax is:
fp =FILE* fopen(const char* filename, const char* mode);
The fopen() function takes two parameters, both of which are strings. The parameter filename is the name of the disk file to open. The file name generally consists of two parts: a primary name and an optional extension, which separates from the primary name by a period (. ). The rules for naming files are determined by your operating system, for example, in MS-DOS. The maximum size of the primary name is 8 characters, and that of an extension is 3 characters. Some valid file names in the MS-DOS system are abc.txt, temp, result.dat etc. when you want to specify the full pathname for the file, use double slash (\\) or single forward-slash (/) as in UNIX and not a single backslash.
The second parameter mode specifies how the file is to be opened, i.e. for reading, writing both reading and writing, appending at the end of the file etc. Allowable modes include read (“r” ),write (“w”) and append (“a”) etc.
If the call to the fopen () function is successful, the function returns a pointer of type FILE. This pointer must use in subsequent operations on the file, such as reading from or writing. If the file cannot open for some reason, fopen () returns a NULL pointer. ·
Now, if fptr is a file pointer pointing to type FILE that you have declared earlier, then the statement,
fptr = fopen( "abc.txt", "r");
opens a text file with the name “abc.txt” and associates it with the file pointer fptr. Because you have specified the mode “r,” so you can only read the file, but you can’t write to this file. The file position will set to the beginning of the data in the file.
If the file locates at C:\mydata\abc.txt, then the string used in the fopen() function should be C:\\mydata\\abc. txt so the statement should be
fptr = fopen( "C:\\mydata\\abc. txt", "r");
If the file locates at abc.txt does not already exist, then fopen() will return NULL, so it is better to check the value returned from the fopen () function in an if statement to make sure that the file is there.
if ( (fptr = fopen( "abc. txt", "r")) == NULL) { printf("cannot open abc.txt\n"); }
Note: There is a limit to the number of files you can open at a particular time. It determines by the value of the constant FOPEN_MAX that defines in stdio.h. FOPEN_MAX is an integer that specifies the maximum number of files that can be open at a time. In C, it is 5.
File Opening Modes
The three basic file operations are reading, writing and appending. These operations can specify a file by using the appropriate file mode. Following are the different modes used with the fopen () function to determine what kind of process is to do to that file :
(a) Read Mode (r): If the file mode is r, it only allows reading from an existing file. The file position will set to the beginning of data in the file. If the file does not exist, it returns NULL It. It should note that the file can only be read, not written.
(b) Write Mode (w): If the file mode is w, it only allows writing to a file. If the file does not exist, a new file with the specified filename created, and the file position will set to the beginning of data in the file. If the file already exists, it will destroy, and a new empty file will create, i.e. its contents are overwritten.
(c) Append Mode (a): Like w mode, the append mode (a) also allows writing to a file but allows writing only at the end of the file. If the file does not exist, a new file with the specified filename creates as in w. However, unlike w, if a file already exists, it will merely reopen, not destroyed first.
(d) Read+ (r+): It is an extension to read mode (r). As with reading mode, a file will open. It not only allows to read a file but also allows to write to it. However, if the file does not already exist, the open operation will fail.
(e) Write+ (w+): It is an extension to write mode (w). As with write mode, a file will create. It not only allows us to write to a file but also to read from it. If a file already exists, it will be first destroyed and then created as an empty file.
(f) Append+ (a+): It opens or creates a file for update. It is similar to append Mode, but its operations are to read existing contents and add new contents at the end of the file, but cannot modify existing contents. The file position pointer is set to point to a first character if a read operation is executed. The file position pointer is set to the last position if a write operation is to execute.
Closing a File
When all operations on a file have complete, it must be closed. As a result, the file disassociates from the file pointer. What happens during a write to a file is that data not written immediately, but it stores in a buffer. When the buffer is full, all its contents write to the disk. Closing the file flushes the data left in the buffer to ensure that no data will be lost before it disassociates the file pointer with the opened file.
Although when the program exits, all open files are closed automatically, however explicitly closing a file has the following advantages,
• Prevents accidental misuse of the file.
• As there is a limit to the number of files that can keep open simultaneously, closing a file may help open another file.
• The closed file can again open in a different mode as per requirement.
In C, a file is closed by the function fclose(). It has the following syntax,
fclose(FILE* fp);
This function accepts a file pointer as an argument and returns a value of type int.
If the fclose() function closes the file successfully, then it returns an integer value 0. Otherwise, it returns EOF. It usually fails when there is no more space left on the disk or removed before the function calls. Disassociates the file pointer fp with the filename associated earlier in fopen(), so fp can no longer access the file it represented.
Read and write to a text file
We use the functions fprintf() and fscanf() to read and write to a text file. They are just the printf() and scanf() file types. The only distinction is that fprint() and fscanf() consider the structure FILE to be indicated.
Example: Write to a text file
#include<stdio.h> #include<stdlib.h> int main() { int num; FILE *fptr; fptr = fopen("C:\\fhandling.txt","w"); if(fptr == NULL) { printf("Error!"); exit(1); } printf("Enter number: "); scanf("%d",&num); fprintf(fptr,"%d",num); fclose(fptr); return 0; }
In this program, the user enters the number and store it in the fhandling.txt. You will see a text file fhandling.txt generated on your computer’s C drive after you compile and execute this code. You will see the integer you entered when you open the file.
Example: Read from a text file
#include <stdio.h> #include <stdlib.h> int main() { int num; FILE *fptr; if ((fptr = fopen("C:\\fhandling.txt","r")) == NULL){ printf("Error! in opening the file"); exit(1); } fscanf(fptr,"%d", &num); printf("Value of n=%d", num); fclose(fptr); return 0; }
This program reads and prints the integer in the fhandling.txt file on the computer. If you successfully generated the file from the illustration above, you would obtain the integer you entered by running this code. Related functions such as fgetchar(), fputc() etc. can be included.
Reading and writing to a binary file
The fread() and fwrite() functions are used in the case of binary files to read and write to a file on the disc.
Writing to a binary file
You must use the fwrite() function to write a binary file. Four arguments are taken from the functions:
• Data address to be written on the disc.
• Data size to be written on the disc.
• Number of such data type.
• Pointer to file. fwrite(addressData, sizeData, numbersData, pointerToFile);
Example: Write to a binary file using fwrite()
#include <stdio.h> #include <stdlib.h> struct ThreeNumber { int n1, n2, n3; }; int main() { int n; struct ThreeNumber num; FILE *fptr; if ((fptr = fopen("C:\\Ofhandling.bin","wb")) == NULL){ printf("Error! opening file"); // Program exits if the file pointer returns NULL. exit(1); } for(n = 1; n < 5; ++n) { num.n1 = n; num.n2 = 5*n; num.n3 = 5*n + 1; fwrite(&num, sizeof(struct ThreeNumber), 1, fptr); } fclose(fptr); return 0; }
We are creating a new Ofhandling.bin file on the C drive in this program. We declare threenum structures with three numbers n1, n2 and n3 and define them as numbers in the main function. Now, within the loop, the value is stored in the file with fwrite(). The first parameter takes the number address, and the second takes the size of the ThreeNumber structure. Since only one instance of the number is inserted, the third parameter is 1. And the last * fptr parameter points to the file that we are storing. At last, we’ve closed the file.
Reading from a binary file
The fread() function also takes 4 similar arguments as above to the fwrite() function.
fread(addressData, sizeData, numbersData, pointerToFile);
Example: Read from a binary file using fread()
#include <stdio.h> #include <stdlib.h> struct ThreeNumber { int n1, n2, n3; }; int main() { int n; struct ThreeNumber num; FILE *fptr; if ((fptr = fopen("C:\\Ofhandling.bin","rb")) == NULL){ printf("Error! opening file"); // Program exits if the file pointer returns NULL. exit(1); } for(n = 1; n < 5; ++n) { fread(&num, sizeof(struct ThreeNumber), 1, fptr); printf("n1: %d\tn2: %d\tn3: %d", num.n1, num.n2, num.n3); } fclose(fptr); return 0; }
Getting data using fseek()
If you have many records inside a file and need to access a record at a certain place, all records must be looped in order to obtain the record.
This will waste a lot of time and memory. Fseek() can be used to make it easier to access the required data.
As the name indicates, fseek() looks for the cursor in the file.
Syntax of fseek()
fseek(FILE * stream, long int offset, int whence);
The first stream parameter is the file pointer. The second parameter is the location of the record to be located, and the third parameter is the starting point of the offset.
Example: fseek()
#include <stdio.h> #include <stdlib.h> struct ThreeNumber { int n1, n2, n3; }; int main() { int n; struct ThreeNumber num; FILE *fptr; if ((fptr = fopen("C:\\Ofhandling.bin","rb")) == NULL){ printf("Error! opening file"); // Program exits if the file pointer returns NULL. exit(1); } // Moves the cursor to the end of the file fseek(fptr, -sizeof(struct ThreeNumber), SEEK_END); for(n = 1; n < 5; ++n) { fread(&num, sizeof(struct ThreeNumber), 1, fptr); printf("n1: %d\tn2: %d\tn3: %d\n", num.n1, num.n2, num.n3); fseek(fptr, -2*sizeof(struct ThreeNumber), SEEK_CUR); } fclose(fptr); return 0; }
This program begins reading and prints the records in the reverse order of the file Ofhandling.bin (last to first).