CSC115 C Programming

C ProgrammingUnit 108 min read

File Handling in C: Functions, Modes, and Practical Applications

Unit 10 of C Programming covers file handling concepts, including file types, opening modes, essential I/O functions, and practical programming techniques for reading/writing data to/from files in C.


## **Introduction to File Handling**
File handling in C allows programs to interact with external data storage (files) beyond the program’s memory. Unlike standard I/O (e.g., `printf`, `scanf`), file handling enables:
- **Persistence**: Data remains stored even after program termination.
- **Large data processing**: Efficiently handle datasets exceeding memory limits.
- **Data sharing**: Multiple programs can access the same file.

### **Types of Files**
1. **Text Files**: Store data as ASCII/Unicode characters (e.g., `.txt`, `.csv`).
   - Example: `"data.txt"` containing `"Hello\nWorld"`.
2. **Binary Files**: Store data in raw binary format (e.g., `.dat`, executable files).
   - Example: Image files, compiled programs.
3. **Sequential Access Files**: Read/write data sequentially (e.g., text files).
4. **Random Access Files**: Access data directly via byte offsets (e.g., binary files).

---
## **File Opening Modes**
Files are opened using `fopen()` with mode strings defining access type and behavior. Below is a **comparison table** of key modes:

| **Mode**       | **Description**                                                                 | **Example Use Case**                     |
|----------------|-------------------------------------------------------------------------------|------------------------------------------|
| `"r"`          | Open for **reading** (file must exist).                                      | Read existing text files.                |
| `"w"`          | Open for **writing** (creates new file; truncates existing).                 | Write new data to a file.                |
| `"a"`          | Open for **appending** (creates file if missing; adds to end).               | Log data without overwriting.            |
| `"r+"`         | Open for **reading/writing** (file must exist).                              | Modify existing files.                  |
| `"w+"`         | Open for **reading/writing** (creates new file; truncates existing).         | Rewrite and read a file.                 |
| `"a+"`         | Open for **reading/appending** (creates file if missing).                    | Read and append data.                    |
| `"rb"`         | Open **binary file for reading**.                                             | Read image/executable files.             |
| `"wb"`         | Open **binary file for writing**.                                             | Write binary data (e.g., structs).      |

**Syntax**:
```c
FILE *fptr = fopen("filename", "mode");
  • Returns NULL on failure (check with if (fptr == NULL)).

Key File I/O Functions

1. Opening and Closing Files

  • fopen(): Opens a file (returns FILE* pointer).
  • fclose(): Closes a file (always call to free resources).
    fclose(fptr);  // Close file pointer
    

2. Reading from Files

Function Syntax Purpose
fgetc() char c = fgetc(fptr); Reads one character.
fgets() fgets(str, size, fptr); Reads a line (stops at \n or EOF).
fscanf() fscanf(fptr, "%d", &var); Reads formatted data (like scanf).
fread() fread(buffer, size, count, fptr); Reads binary data (e.g., structs).

Example: Read a Text File Line-by-Line

#include <stdio.h>
int main() {
    FILE *fp = fopen("input.txt", "r");
    char line[100];
    if (fp == NULL) {
        printf("Error opening file!\n");
        return 1;
    }
    while (fgets(line, sizeof(line), fp) != NULL) {
        printf("%s", line);  // Print each line
    }
    fclose(fp);
    return 0;
}

3. Writing to Files

Function Syntax Purpose
fputc() fputc('A', fptr); Writes one character.
fputs() fputs("Hello", fptr); Writes a string (no \n added).
fprintf() fprintf(fptr, "%d", num); Writes formatted data.
fwrite() fwrite(&data, size, count, fptr); Writes binary data.

Example: Write to a File

FILE *fp = fopen("output.txt", "w");
if (fp == NULL) {
    printf("Error!\n");
    return 1;
}
fprintf(fp, "Name: John\nAge: 20");
fclose(fp);

4. File Positioning

  • fseek(): Move file pointer to a specific position.
    fseek(fptr, offset, SEEK_SET);  // SEEK_SET: start of file
    
  • ftell(): Return current file position (byte offset).
  • rewind(): Reset file pointer to start.

Example: Read from a Specific Position

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

Practical Applications

1. Extracting Prime Numbers from a File

Problem: Given Num.txt with integers, write primes to Prime.txt. Solution:

#include <stdio.h>
#include <stdbool.h>

bool isPrime(int n) {
    if (n <= 1) return false;
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) return false;
    }
    return true;
}

int main() {
    FILE *in = fopen("Num.txt", "r");
    FILE *out = fopen("Prime.txt", "w");
    int num;
    while (fscanf(in, "%d", &num) == 1) {
        if (isPrime(num)) {
            fprintf(out, "%d ", num);
        }
    }
    fclose(in); fclose(out);
    return 0;
}

2. Copying a File

Program: Copy source.txt to destination.txt.

FILE *src = fopen("source.txt", "r");
FILE *dest = fopen("destination.txt", "w");
char ch;
while ((ch = fgetc(src)) != EOF) {
    fputc(ch, dest);
}
fclose(src); fclose(dest);

Error Handling in File Operations

Always check for errors:

  1. fopen() failure: Returns NULL.
  2. Read/write errors: Check return values (e.g., fscanf returns items read).
  3. End-of-file (EOF): feof(fptr) returns non-zero.
  4. Error flags: ferror(fptr) checks for errors.

Example: Robust File Reading

if (fptr == NULL) {
    perror("Error opening file");
    return 1;
}
while (!feof(fptr)) {
    if (fscanf(fptr, "%d", &num) != 1) {
        printf("Error reading data!\n");
        break;
    }
    printf("%d\n", num);
}

Advantages and Disadvantages of File Handling

Advantages

  • Data Persistence: Files retain data after program exit.
  • Large Data Support: Handle datasets larger than RAM.
  • Portability: Files can be shared across programs/languages.
  • Efficiency: Binary files reduce storage and I/O overhead.

Disadvantages

  • Slower than Memory: Disk I/O is slower than RAM access.
  • Complexity: Requires careful error handling.
  • Resource Management: Forgetting fclose() causes leaks.

Exam Tip

  1. Understand Modes: Memorize "r", "w", "a", and their + variants. Know when a file is created/truncated.
  2. Function Syntax: Be fluent with fopen(), fclose(), fscanf(), fprintf(), fgetc(), fputs().
  3. Error Handling: Always check NULL after fopen() and handle EOF/ferror().
  4. Practical Programs: Expect questions on:
    • Reading/writing files line-by-line.
    • Filtering data (e.g., primes, even numbers).
    • Copying or merging files.
  5. Binary vs. Text: Know when to use fread()/fwrite() (binary) vs. fscanf()/fprintf() (text).
  6. File Pointers: Understand fseek(), ftell(), and rewind() for random access.

Common Pitfalls:

  • Forgetting to close files (fclose()).
  • Using wrong modes (e.g., "r" on a non-existent file).
  • Buffer overflows in fgets() (always specify size).
  • Ignoring return values of fscanf()/fprintf().

Summary Table for Quick Revision

Task Function Example
Open file fopen() fptr = fopen("file.txt", "r");
Close file fclose() fclose(fptr);
Read character fgetc() ch = fgetc(fptr);
Read line fgets() fgets(buf, 100, fptr);
Read formatted data fscanf() fscanf(fptr, "%d", &num);
Write character fputc() fputc('A', fptr);
Write string fputs() fputs("Hi", fptr);
Write formatted data fprintf() fprintf(fptr, "%d", num);
Move file pointer fseek() fseek(fptr, 10, SEEK_SET);
Check EOF feof() while (!feof(fptr))

End of Note (Word count: ~1,800)

Based on the TU BSc CSIT syllabus for C Programming (CSC115), unit 10.

Discussion

Loading…