File Handling in C

What is File Handling in C ?

File handling is a fundamental aspect of programming in C. It allows developers to read from and write to files, crucial for tasks like data storage, retrieval, and manipulation.

1. Getting Started with File Handling

1.1 Opening and Closing Files

The foundation of file handling starts with opening and closing files. The fopen() function is used to open a file, and fclose() ensures resources are freed up.

Example:

FILE *filePtr;
filePtr = fopen("data.txt", "r");
// Perform operations on the file
fclose(filePtr);

1.2 Reading Data from Files

To read data, functions like fgetc() for individual characters and fgets() for lines of text are employed.

Example:

char ch;
ch = fgetc(filePtr);

1.3 Writing Data to Files

Writing data involves using fputc() for characters and fputs() for lines of text.

Example:

char data[] = "Hello, World!";
fputs(data, filePtr);

2. Working with Text Files

2.1 Reading and Writing Characters

Reading and writing characters can be achieved with fgetc() and fputc().

Example:

while ((ch = fgetc(filePtr)) != EOF) {
    // Process character
}

2.2 Reading and Writing Lines of Text

fgets() reads lines and fputs() writes lines.

Example:

char buffer[100];
while (fgets(buffer, sizeof(buffer), filePtr) != NULL) {
    // Process line of text
}

2.3 Advanced Formatting with fprintf() and fscanf()

fprintf() enables formatted output to files, while fscanf() facilitates formatted input.

Example:

fprintf(filePtr, "Name: %s, Age: %d", name, age);
fscanf(filePtr, "Name: %s, Age: %d", name, &age);

3. Binary File Handling

3.1 Reading and Writing Binary Data

Binary file handling, facilitated by fread() and fwrite(), allows for efficient data storage and retrieval.

Example:

struct Student {
    char name[50];
    int age;
};
fread(&student, sizeof(struct Student), 1, filePtr);

3.2 Organizing Structured Data

Binary files are often used for storing structured data efficiently. Here’s an example of how to write structured data to a binary file:

Example:

fwrite(&student, sizeof(struct Student), 1, filePtr);

4. Error Handling and Validation

4.1 Checking for File Existence

You can use the access() function to check if a file exists.

Example:

if (access("data.txt", F_OK) != -1) {
    // File exists
}

4.2 Effective Error Handling with perror() and strerror()

Robust error handling can be achieved using perror() and strerror().

Example:

if (filePtr == NULL) {
    perror("Error opening file");
    printf("Error: %s\n", strerror(errno));
}

4.3 Utilizing Error Codes and errno

Understanding error codes and the errno variable is crucial for comprehensive error detection and handling.

5. File Pointers and Seeking

5.1 Understanding the File Position Indicator

The file position indicator keeps track of your position in the file.

Example:

long pos = ftell(filePtr);

5.2 Navigating the File with fseek()

The fseek() function is used to move the file pointer to a specific location within the file.

Example:

fseek(filePtr, 0, SEEK_SET); // Move to the beginning

5.3 Random Access with ftell()

ftell() helps achieve random access to files by returning the current file position.

long currentPos = ftell(filePtr);

Example with all the functions of file handling in C:

#include <stdio.h>
#include <stdlib.h>

int main() {
    // File pointer
    FILE *filePtr;

    // Open a file for writing
    filePtr = fopen("example.txt", "w");

    // Check if file opened successfully
    if (filePtr == NULL) {
        perror("Error opening file");
        return 1;
    }

    // Writing data to the file
    char data[] = "Hello, World!\n";
    fputs(data, filePtr);

    // Close the file
    fclose(filePtr);

    // Open the same file for reading
    filePtr = fopen("example.txt", "r");

    // Check if file opened successfully
    if (filePtr == NULL) {
        perror("Error opening file");
        return 1;
    }

    // Read and display data from the file
    char buffer[100];
    while (fgets(buffer, sizeof(buffer), filePtr) != NULL) {
        printf("Data from file: %s", buffer);
    }

    // Close the file
    fclose(filePtr);

    // Reopen the file for appending
    filePtr = fopen("example.txt", "a");

    // Check if file opened successfully
    if (filePtr == NULL) {
        perror("Error opening file");
        return 1;
    }

    // Append more data to the file
    char newData[] = "Appending more data.\n";
    fputs(newData, filePtr);

    // Close the file
    fclose(filePtr);

    // Open the file for reading again
    filePtr = fopen("example.txt", "r");

    // Check if file opened successfully
    if (filePtr == NULL) {
        perror("Error opening file");
        return 1;
    }

    // Read and display data from the file
    while (fgets(buffer, sizeof(buffer), filePtr) != NULL) {
        printf("Data from file: %s", buffer);
    }

    // Close the file
    fclose(filePtr);

    return 0;
}

Output:

Data from file: Hello, World!
Data from file: Appending more data.

In above example:

  1. We include the necessary header files, <stdio.h> for file operations and <stdlib.h> for error handling.
  2. We open a file named “example.txt” for writing using fopen() with the mode “w”, which creates a new file or truncates an existing one. We check if the file opened successfully using if (filePtr == NULL).
  3. We write the string “Hello, World!\n” to the file using fputs().
  4. We close the file using fclose().
  5. We reopen the same file for reading and display the content using fgets() in a loop.
  6. We reopen the file for appending using the mode “a” and append the string “Appending more data.\n”.
  7. We reopen the file for reading again and display the updated content.