ITM102 Structured Programming in C

Structured Programming in CUnit 613 min read

File Handling in C: Operations, Modes, and Real-World Applications

Unit 6 of Structured Programming in C covers file handling in C, including file types (text/binary), opening/closing files, reading/writing operations, and error handling. It explains how to manipulate files using standard library functions (fopen, fclose, fprintf, fscanf, etc.) and demonstrates practical applications

TAKEAWAYS:

  • Understand the two types of files in C: text files (ASCII characters) and binary files (raw data), and when to use each.
  • Master file operations: opening (fopen), closing (fclose), reading (fscanf, fgets), writing (fprintf, fputs), and positioning (fseek, rewind).
  • Learn file modes ("r", "w", "a", "rb", "wb") and their implications for file creation/overwriting/appending.
  • Handle errors gracefully using NULL checks and ferror/feof functions.
  • Apply file handling to real-world scenarios like storing student records, logging transactions, or managing configurations.
  • Compare sequential vs. random access in files and their performance trade-offs.

1. Introduction to File Handling

Files are persistent storage units that allow programs to store data between executions. Unlike variables (which exist only in memory), files retain data even after the program terminates. In C, files are handled using the Standard I/O (stdio.h) library, which provides functions to interact with files.

Why Use Files?

  • Data Persistence: Save data (e.g., user profiles, transaction logs) for future use.
  • Large Data Handling: Process data that doesn’t fit in memory (e.g., databases, logs).
  • Inter-Process Communication: Share data between programs (e.g., configuration files).
  • Backup and Recovery: Store critical data securely.

Types of Files in C

Type Description Example Use Case
Text Files Store data as ASCII characters (human-readable). Log files, CSV data, configuration files.
Binary Files Store data in raw binary format (faster, compact). Image files, executable files, databases.

2. File Operations in C

File Pointers (FILE*)

Every file in C is accessed via a file pointer (FILE*), declared in stdio.h. Common file pointers:

  • stdin (Standard Input, keyboard)
  • stdout (Standard Output, screen)
  • stderr (Standard Error, error messages)

Opening a File (fopen)

Syntax:

FILE *fptr = fopen("filename", "mode");

Modes:

Mode Description
"r" Open for reading (file must exist).
"w" Open for writing (creates file; truncates if exists).
"a" Open for appending (creates file if doesn’t exist).
"r+" Open for reading and writing (file must exist).
"rb" Open binary file for reading.
"wb" Open binary file for writing.

Example: Opening a File

FILE *fp = fopen("student.txt", "w");
if (fp == NULL) {
    printf("Error opening file!\n");
    exit(1);
}

Visual: File Opening Modes

flowchart TD
    A["fopen(\"file.txt\", \"r\")"] -->|"File exists"| B["Success: Read mode"]
    A -->|"File doesn't exist"| C["Error: NULL"]
    D["fopen(\"file.txt\", \"w\")"] --> E["Success: Write mode (creates/truncates)"]
    F["fopen(\"file.txt\", \"a\")"] --> G["Success: Append mode (creates if missing)"]

3. Reading and Writing Files

Writing to a File (fprintf, fputs)

  • fprintf: Write formatted data (like printf but to a file).
  • fputs: Write a string (including newline).

Example: Writing Student Records

fprintf(fp, "%s %d %s %d\n", name, id, address, age);
fputs("End of record\n", fp);

Reading from a File (fscanf, fgets)

  • fscanf: Read formatted data (like scanf but from a file).
  • fgets: Read a line (including spaces).

Example: Reading Student Records

char name[50], address[100];
int id, age;
fscanf(fp, "%s %d %s %d", name, &id, address, &age);

Visual: File Read/Write Process

sequenceDiagram
    participant Program
    participant File
    Program->>File: fopen("data.txt", "w")
    File-->>Program: File pointer
    Program->>File: fprintf(data)
    Program->>File: fclose()
    Program->>File: fopen("data.txt", "r")
    File-->>Program: File pointer
    Program->>File: fscanf(data)
    Program->>File: fclose()

4. Closing a File (fclose)

Always close files to:

  • Free system resources.
  • Ensure data is flushed (written) to disk.
if (fclose(fp) != 0) {
    printf("Error closing file!\n");
}

5. Error Handling in File Operations

Check for errors using:

  • NULL check after fopen.
  • ferror(fp): Check for read/write errors.
  • feof(fp): Check for end-of-file.

Example: Safe File Operations

FILE *fp = fopen("data.txt", "r");
if (fp == NULL) {
    printf("File not found!\n");
    return 1;
}
while (!feof(fp)) {
    char line[100];
    if (fgets(line, 100, fp) == NULL) break;
    printf("%s", line);
}
fclose(fp);

6. Binary File Handling

Binary files store data exactly as in memory (no text conversion). Use modes "rb" or "wb".

Example: Writing Binary Data

int num = 100;
fwrite(&num, sizeof(int), 1, fp);

Example: Reading Binary Data

int num;
fread(&num, sizeof(int), 1, fp);
printf("Read: %d\n", num); // Output: 100

Visual: Text vs. Binary File Storage

flowchart LR
    A["Text File"] --> B["ASCII: '1','0','0','\n'"]
    C["Binary File"] --> D["Raw bytes: 0x00 0x64 0x00 0x00"]

7. Random Access in Files (fseek, rewind)

  • fseek(fp, offset, whence): Move file pointer to a specific position.
    • whence: SEEK_SET (start), SEEK_CUR (current), SEEK_END (end).
  • rewind(fp): Reset pointer to the start.

Example: Reading a Specific Record

fseek(fp, 100, SEEK_SET); // Move to 100th byte
char ch = fgetc(fp);      // Read character at position 100

Visual: File Pointer Movement

flowchart TD
    A["Initial Position"] -->|"fseek(100, SEEK_SET)"| B["Position 100"]
    B -->|"fseek(-20, SEEK_CUR)"| C["Position 80"]
    C -->|"rewind()"| D["Position 0"]

8. Real-World Applications

In the Real World

  1. eSewa (Nepal):

    • Uses binary files to store transaction logs securely. Each transaction is written in binary format for speed and compactness.
    • Example: When you pay a bill, eSewa writes your transaction details (amount, date, user ID) to a binary log file for auditing.
  2. Khalti (Nepal):

    • Employs text files (CSV/JSON) to store user transaction histories. These files are later processed to generate monthly statements.
    • Example: Your Khalti transaction data is stored in a CSV file like:
      user_id,amount,date,status
      12345,500,2023-10-15,completed
      
  3. Daraz (Nepal):

    • Uses file handling to manage order queues. When you place an order, it’s written to a text file (orders.txt) and processed by the fulfillment team.
    • Example: A line in orders.txt:
      order_id:ORD123,product:Laptop,status:processing
      
  4. NTC (Nepal Telecom):

    • Stores customer call logs in binary files for faster retrieval. Each call record (number, duration, timestamp) is written as binary data.
    • Example: Binary file structure for a call log:
      [8 bytes: timestamp][4 bytes: duration][20 bytes: phone number]
      
  5. Banks (e.g., NMB, Global IME):

    • Use file handling to maintain customer account data. Loan details, transaction histories, and interest calculations are stored in files.
    • Example: Calculating monthly interest for a loan:
      // Pseudocode for bank loan interest calculation
      FILE *fp = fopen("loans.txt", "r+");
      float principal, rate, interest;
      fscanf(fp, "%f %f", &principal, &rate);
      interest = principal * (rate / 100) / 12; // Monthly interest
      fprintf(fp, "Monthly Interest: %.2f\n", interest);
      fclose(fp);
      

9. Worked Example: Student Record Management

Task: Write a program to store 5 student records in student.txt and display them.

Step-by-Step Code

#include <stdio.h>
struct Student {
    char name[50];
    int id;
    char address[100];
    int age;
};
int main() {
    struct Student s[5];
    FILE *fp;

    // Step 1: Write records to file
    fp = fopen("student.txt", "w");
    for (int i = 0; i < 5; i++) {
        printf("Enter name, ID, address, age: ");
        scanf("%s %d %s %d", s[i].name, &s[i].id, s[i].address, &s[i].age);
        fprintf(fp, "%s %d %s %d\n", s[i].name, s[i].id, s[i].address, s[i].age);
    }
    fclose(fp);

    // Step 2: Read and display records
    fp = fopen("student.txt", "r");
    printf("\nStudent Records:\n");
    while (fscanf(fp, "%s %d %s %d", s[0].name, &s[0].id, s[0].address, &s[0].age) != EOF) {
        printf("%s %d %s %d\n", s[0].name, s[0].id, s[0].address, s[0].age);
    }
    fclose(fp);
    return 0;
}

Trace of Execution

Step Action File Content After Step
1 Open student.txt in write mode (File created, empty)
2 Enter student 1 data Ram 101 Kathmandu 20
3 Enter student 2 data Ram 101 Kathmandu 20\nSita 102 Pokhara 21
4 Close file File saved with 5 records.
5 Open student.txt in read mode (File reopened)
6 Read and display records Output: All 5 records printed.

Visual: File After Writing 3 Records


10. Comparison: Text vs. Binary Files

Feature Text Files Binary Files
Storage ASCII characters (larger size) Raw bytes (compact)
Readability Human-readable Not human-readable
Speed Slower (conversion overhead) Faster (direct memory access)
Use Case Logs, configs, CSV data Images, databases, executables
Portability Platform-independent Platform-dependent (endianness issues)

11. Advantages and Disadvantages

Advantages of File Handling

  • Persistence: Data survives program termination.
  • Large Data Support: Handle datasets larger than memory.
  • Security: Restrict access to sensitive data (e.g., passwords in encrypted files).
  • Interoperability: Share data between programs (e.g., CSV for Excel).

Disadvantages

  • Slower than Memory: Disk I/O is slower than RAM access.
  • Error-Prone: Risk of corruption if not handled properly.
  • Complexity: Requires careful management of file pointers and modes.

12. Common Pitfalls and Best Practices

Pitfalls

  1. Forgetting to close files: Leads to resource leaks.
  2. Not checking fopen return value: Causes crashes if file doesn’t exist.
  3. Buffer overflows: Using fgets without length checks.
  4. Mixing text/binary modes: Corrupts data (e.g., writing binary to text mode).

Best Practices

  1. Always check fopen for NULL.
  2. Use fclose in else blocks or finally (e.g., with goto).
  3. Prefer fgets over gets (avoids buffer overflows).
  4. For binary files, use fixed-size reads/writes.
  5. Document file formats (e.g., "Record 1: 4 bytes ID, 50 bytes name").

13. Exam Tip

How This Unit is Examined

  1. Short Questions (2-5 marks):

    • Define fopen, fclose, fscanf.
    • Difference between "r", "w", "a" modes.
    • When to use text vs. binary files.
  2. Programming Questions (10-15 marks):

    • Write a program to:
      • Create a file and store n student records.
      • Read and display records from a file.
      • Append data to an existing file.
      • Use fseek to update a specific record.
    • Example Question:

      "Define a structure employee with fields id, name, salary. Write a program to store 3 employee records in a binary file emp.dat and then display the highest salary."

  3. Debugging (5 marks):

    • Identify errors in given code (e.g., missing fclose, incorrect mode).

Key Formulas/Concepts to Remember

  • File modes: "r", "w", "a", "r+", "rb", "wb".
  • fseek offsets: SEEK_SET, SEEK_CUR, SEEK_END.
  • Binary file size: sizeof(data_type) * number_of_items.

Model Answer Structure for Programming Questions

  1. Include necessary headers: #include <stdio.h>.
  2. Define structures (if required).
  3. Open file with error check:
    FILE *fp = fopen("filename", "mode");
    if (fp == NULL) { printf("Error!"); exit(1); }
    
  4. Perform operations (read/write/append).
  5. Close file:
    fclose(fp);
    
  6. Handle edge cases: Empty file, EOF, large data.

14. Summary Checklist

Before the exam, ensure you can:

  • Explain the difference between text and binary files.
  • List all file modes and their uses.
  • Write code to:
    • Create/write to a file.
    • Read from a file.
    • Append to a file.
    • Use fseek for random access.
  • Handle file errors (NULL, feof, ferror).
  • Apply file handling to real-world scenarios (e.g., student records, transaction logs).

Based on the TU BITM syllabus for Structured Programming in C (ITM102), unit 6.

Discussion

Loading…