File Handling in C

The console I/O functions like printf and scanf are used to print the data on the screen and read the data from the keyboard respectively.

These functions handle small amounts of data efficiently. But in real life, we have to process a large amount of data. The standard I/O functions have two major problems.

  1. These functions take more time to handle the data.
  2. The data will be lost when the program is terminated or when the computer is turned off.

To avoid these problems data can be stored on secondary storage devices in the form of tapes and disks.

Data can be stored on disks by using file handling in C.

File:

A file is a place on a disc where a group of related data is stored permanently.

Files can be read and modified as per the user’s requirement.

Files must be open before performing any operations on the file.

When the file is opened it is associated with a communication channel or connection.

The file can be opened either by a stream or file descriptor.

Stream:

Stream is a high-level interface for performing I/O operations. Stream is a buffer. During input operation, the data flows from keyboard to the program with the help of a stream.

During output operation, the data flows from the program to monitor with the help of a stream.

There are two kinds of streams.

Standard Stream: 

There are three standard streams such as

  1. stdin: It is used to read the data from the input device and give it to the program.
  2. stdout: It is used to write the data from the program to the output device.
  3. stderr: This is also an output string used to write the errors on the screen.

The streams can be open for reading the data, writing the data, as well as both.

The standard streams are opened automatically when the program is executed and closed automatically when the program is terminated.

File Stream: 

These are the user-defined streams used to read the data from the file as well as to write the data from the file.

File Descriptor: File Descriptor is a low-level interface for performing file I/O operations.

Different types of Files:

 The different types of files are text files and binary files.

Text File: 

  • Files that contain textual information which is in the form of letters, numbers, and symbols are called text files. Text files can be easily read and understood by the user.
  • The data contained in the text files can be read by a word processor.
  • The text file uses only 7 bits allowing the 8th bit to be zero.

Binary File: 

  • Binary File is a file which contains the data in the form of zeroes and ones. 
  • The binary files can be easily interpreted and understood by the computer system. 
  • In the computer system, all the executable files (.exc) and dynamic link library files (.dll) are treated as binary files. 
  • Binary files cannot be opened in the word processor. The binary file uses all the 8 bits to store the information.

Different ways of accessing the files:

The data which is present in the file can be accessed in 3 different ways.

1. Sequential Access: 

  • In this method, the data is stored and accessed sequentially one after the other. 
  • The data stored in this file will be based on the key field. 
  • The main advantage is that we can enter the data very easily. 
  • The disadvantage is it takes a lot of time to search the data.

2. Index Sequential Access: 

  • In this method, it maintains two files, as index file and a sequential file.
  •  In the sequential file, the data is stored in sequential order based on the key field. 
  • The index file will have the key field along with the pointer so that it gives the location of data in a sequential file.

3. Random Access: 

  • In this method, the data can be stored and retrieved randomly. 
  • In this method, we use some techniques to access the data directly.  
  • The most common technique that we used is called the hash function. With the help of the hash function, we can store and retrieve the data very fast.

C program using File Handling

#include <stdio.h>
#include <stdlib.h>
int main() {
    FILE *fptr;     // File pointer
    char filename[100], c;
    // Get filename from the user
    printf("Enter the filename to open: ");
    scanf("%s", filename);
    // Open file in read mode
    fptr = fopen(filename, "r"); 
    // Check for errors opening the file
    if (fptr == NULL) {
        perror("Error opening file");
        return -1;
    }
    printf("\nContents of the file:\n");
    // Read file character by character
    c = fgetc(fptr); 
    while (c != EOF) {  // Continue until end of file
        printf("%c", c); 
        c = fgetc(fptr);
    }
    // Close the file
    fclose(fptr); 
    printf("\n-----------------------------\n");
    printf("Now, let's append some text!\n");
    // Open file in append mode (create if not exists)
    fptr = fopen(filename, "a");
    
    // Check for errors
    if (fptr == NULL) {
        perror("Error opening file");
        return -1;
    }
    fprintf(fptr, "\nThis text is appended at the end of the file.\n");
    printf("Text successfully appended.\n");
    // Close the file again
    fclose(fptr);
    return 0;
}

Output:

Enter the filename to open: helloworld
Error opening file: No such file or directory

Error handling Functions in Files

During file I/O operations there is a possibility of error. The possibility of occurring the errors are

  1. Opening a file with an invalid name.
  2. Opening a file to perform one operation but the file is opened for other operations.
  3. Reading the data beyond the end of the file.

The two file status functions are FEOF() and FERROR().

FEOF(): This function is used to detect whether the file pointer has reached EOF or not. When EOF is reached, this function returns non-zero value otherwise it returns 0 value.

The syntax is 

FEOF(file pointer);

Ex: FEOF(P);

FERROR(): This function returns a non-zero value when an error occurs while opening the file. Otherwise it returns a zero value.

Binary File I/O functions or Block I/O functions

The functions fread and fwrite are used as binary I/O functions. These functions are used to read and write record structures or block into the file. These functions are also called direct I/O functions.

fread(): This function is used to read a record from the file.

The syntax is 

fread(&struct variable, size off(struct variable), n, file pointer);  

where n stands for number of records.

fwrite(): This function is used to write the record into the file. 

The syntax is

 fwrite(&struct variable, size off(struct variable), n, file pointer);

FAQs of File Handling in C

Q1. What are the different file opening modes in C, and when would you use each one?

  • “r” (Read): Opens an existing file for reading. If the file doesn’t exist, it returns an error.
  • “w” (Write): Opens a file for writing. If the file exists, its content is overwritten. If it doesn’t exist, a new file is created.
  • “a” (Append): Opens a file for appending. New data is added to the end of the file. If the file doesn’t exist, a new one is created.
  • “r+” (Read/Write): Opens an existing file for both reading and writing. The file pointer is positioned at the beginning.
  • “w+” (Read/Write): Opens a file for both reading and writing. If the file exists, its content is overwritten. If it doesn’t exist, a new one is created.
  • “a+” (Read/Append): Opens a file for both reading and appending. New data is added to the end. If the file doesn’t exist, a new one is created.

Q2. Explain the concept of file pointers and how they are used in C file handling.

  • A file pointer (FILE *) is a special type of pointer variable that stores the address of a FILE structure.
  • The FILE structure contains information about the file being accessed, such as its name, location, and current position.
  • File pointers are obtained using the fopen() function and are used as arguments to other file I/O functions (e.g., fgetc, fgets, fprintf).
  • They allow you to control the position within a file and perform read/write operations.

Q3. How would you read a line of text from a file in C?

You can use the fgets() function:

char line[256]; // Assuming maximum line length
FILE *fptr = fopen("filename.txt", "r");
if (fptr != NULL) {
    while (fgets(line, sizeof(line), fptr) != NULL) {
        // Process the line (e.g., print it)
        printf("%s", line);
    }
    fclose(fptr);
}

Q4. What is the difference between text files and binary files? How does C handle them differently?

  • Text Files: Contain characters organized into lines. Newlines (\n) are used to separate lines. C functions like fgets() and fprintf() are designed for text files.
  • Binary Files: Contain raw bytes of data (e.g., images, executable programs). C functions like fread() and fwrite() are used for binary files.

Q5. How do you check for errors during file operations in C?

  • Return Values: Most file I/O functions return special values (like NULL for fopen()) or error codes to indicate failure.
  • feof(): This function checks if the end of file has been reached.
  • ferror(): This function checks if an error has occurred during file operations.
  • perror(): This function prints a descriptive error message to the standard error stream.

Example Error Handling:

FILE *fptr = fopen("filename.txt", "r");
if (fptr == NULL) {
    perror("Error opening file");
    return -1; // Or handle the error appropriately
}
// ... file operations ...
if (ferror(fptr)) {
    perror("Error reading file");
    fclose(fptr);
    return -1;
}
fclose(fptr);
Scroll to Top