Programming In CUnit 1114 min read
File Handling in C: Modes, Operations, and Structured Data Storage
Unit 11 of Programming In C covers file handling in C—how to create, read, write, and manipulate files using standard library functions (fopen, fclose, fprintf, fscanf, etc.), file opening modes, error handling, and integrating file operations with structures for real-world data storage (e.g., student records, employee
TAKEAWAYS:
- File modes matter: Modes like
"r","w","a", and"rb"determine how a file is opened (read-only, write-only, append, binary), and mixing them incorrectly causes runtime errors. - Structures + files = databases: Store structured data (e.g.,
studentrecords) in files to persist beyond program execution, mimicking real-world systems like eSewa’s user data or bank transaction logs. - Error handling is critical: Always check if
fopen()returnsNULLand handle file operations gracefully to avoid crashes (e.g., when a file doesn’t exist). - Binary vs. text files: Binary mode (
"wb","rb") preserves exact data (e.g., images, serialized objects), while text mode ("w","r") adds newline conversions—choose based on use case. - Sequential vs. random access: Sequential access (line-by-line) is simple but slow for large files; random access (
fseek) enables direct jumps (e.g., updating a specific student record). - Real-world tie-ins: File handling powers apps like Khalti (transaction logs), Daraz (order databases), and NTC (bill records), where data must persist across sessions.
1. Why File Handling?
Programs often need to store data permanently (beyond runtime). Without files:
- All data is lost when the program exits.
- No way to share data between runs (e.g., a bank app can’t track accounts without saving them).
Example: When you log into eSewa, your transaction history isn’t recreated every time you open the app—it’s stored in a file (or database) on the server. Similarly, Ncell stores your call logs in files to bill you accurately.
2. File Opening Modes
Files in C are opened using fopen(), which takes two arguments:
- Filename (e.g.,
"students.txt"). - Mode (a string specifying how to open the file).
| Mode | Description | Example Use Case |
|---|---|---|
"r" |
Open for reading (file must exist). | Displaying student records. |
"w" |
Open for writing (creates/truncates file). | Saving new employee data. |
"a" |
Open for appending (adds to end of file). | Logging transactions in Khalti. |
"r+" |
Open for reading + writing (file must exist). | Updating a Daraz order status. |
"w+" |
Open for writing + reading (creates/truncates file). | Editing a bank’s loan records. |
"a+" |
Open for appending + reading (adds to end of file). | Adding new NTC bill entries. |
"rb" |
Open binary file for reading. | Loading an image (e.g., profile pic in Pathao). |
"wb" |
Open binary file for writing. | Saving a serialized object (e.g., game save). |
Visual: File Modes in Action
flowchart TD
A["fopen(\"data.txt\", \"w\")"] -->|"Creates/Truncates"| B["File: Empty"]
C["fopen(\"data.txt\", \"a\")"] -->|"Appends"| D["File: Old data + new"]
E["fopen(\"data.txt\", \"r\")"] -->|"Reads"| F["File: Unchanged"]Worked Example: Opening a File
#include <stdio.h>
int main() {
FILE *fp = fopen("students.txt", "r"); // Open for reading
if (fp == NULL) {
printf("Error opening file!\n");
return 1;
}
fclose(fp); // Always close the file
return 0;
}
Trace:
| Step | Action | File State |
|---|---|---|
fopen() |
Opens "students.txt" in "r" |
File exists → OK |
fp == NULL |
Checks for error | fp points to file |
fclose() |
Closes file | File remains on disk |
3. File Operations
Once a file is open, use these functions:
| Function | Purpose | Example |
|---|---|---|
fprintf() |
Write formatted data to file. | fprintf(fp, "%s\n", name); |
fscanf() |
Read formatted data from file. | fscanf(fp, "%d", &rollno); |
fgets() |
Read a line (including spaces) from file. | fgets(buffer, 100, fp); |
fputs() |
Write a string to file. | fputs("Hello\n", fp); |
fseek() |
Move file pointer to a specific position (bytes from start). | fseek(fp, 100, SEEK_SET); |
ftell() |
Return current position of file pointer. | long pos = ftell(fp); |
rewind() |
Reset file pointer to start. | rewind(fp); |
Visual: File Pointer Movement
flowchart LR
A["Start"] -->|"fseek(fp, 50, SEEK_SET)"| B["Move to byte 50"]
B -->|"fread()"| C["Read 10 bytes"]
C -->|"ftell()"| D["Current pos: 60"]
D -->|"rewind()"| AWorked Example: Writing to a File
#include <stdio.h>
struct Student {
char name[50];
int rollno;
};
int main() {
FILE *fp = fopen("students.txt", "w");
struct Student s1 = {"Ramesh", 101};
fprintf(fp, "%s %d\n", s1.name, s1.rollno); // Write to file
fclose(fp);
return 0;
}
File After Execution:
Ramesh 101
4. Storing Structured Data in Files
Problem: Past exam questions often ask to store records (e.g., students, employees) in files and retrieve specific entries. This mimics real-world systems like:
- NTC: Storing bill records for each customer.
- Banks: Saving account details for loan processing.
- Daraz: Managing order statuses.
Step-by-Step: Storing and Retrieving Student Records
- Define a structure:
struct Student { char name[50]; int rollno; char college[50]; }; - Write records to file:
FILE *fp = fopen("students.dat", "wb"); // Binary mode for exact storage struct Student s1 = {"Sita", 201, "SoE"}; fwrite(&s1, sizeof(struct Student), 1, fp); // Write one record fclose(fp); - Read and filter records (e.g., find students from "SoE"):
fp = fopen("students.dat", "rb"); struct Student s; while (fread(&s, sizeof(struct Student), 1, fp) == 1) { if (strcmp(s.college, "SoE") == 0) { printf("%s %d\n", s.name, s.rollno); // Display matching records } } fclose(fp);
Visual: Binary File Storage
Trace for Filtering:
| Step | Action | File Pointer | Output |
|---|---|---|---|
fopen("rb") |
Open binary file | Start | — |
fread() (1st) |
Read Record 1 ("Sita") | 0x007A | — |
strcmp("SoE") |
Match found | 0x007A | "Sita 201" printed |
fread() (2nd) |
Read Record 2 ("Ram") | EOF | — |
| Loop ends | EOF reached | — | — |
5. Text vs. Binary Files: Key Differences
| Feature | Text Files ("r", "w") |
Binary Files ("rb", "wb") |
|---|---|---|
| Data Format | Human-readable (ASCII/Unicode) | Exact byte representation |
| Use Case | Logs, CSV data | Images, serialized objects |
| Speed | Slower (conversions) | Faster (direct memory access) |
| Portability | Limited (line endings vary) | High (platform-independent) |
| Example | students.txt (CSV) |
profile.png (image) |
Real-World Example:
- Khalti uses binary files/databases to store transaction hashes (exact byte storage for security).
- Daraz uses text files for order logs (human-readable for audits).
6. Error Handling in File Operations
Always check for errors when opening files:
FILE *fp = fopen("nonexistent.txt", "r");
if (fp == NULL) {
perror("Error"); // Prints: "Error: No such file or directory"
return 1;
}
Common Errors:
NULLpointer: File not found or permission denied.fprintf()/fscanf()failure: Disk full or corrupted file.
Worked Example: Safe File Writing
FILE *fp = fopen("backup.dat", "wb");
if (fp == NULL) {
printf("Backup failed!\n");
exit(1);
}
int data = 42;
if (fwrite(&data, sizeof(int), 1, fp) != 1) {
printf("Write error!\n");
}
fclose(fp);
7. Random Access vs. Sequential Access
| Method | Description | Example Use Case |
|---|---|---|
| Sequential | Read/write line-by-line (slow for large files). | Reading a log file (e.g., NTC bills). |
| Random | Jump to any position using fseek() (fast for large files). |
Updating a specific student record. |
Worked Example: Random Access
FILE *fp = fopen("students.dat", "rb");
struct Student s;
fseek(fp, 2 * sizeof(struct Student), SEEK_SET); // Jump to 3rd record
fread(&s, sizeof(struct Student), 1, fp);
printf("Record 3: %s %d\n", s.name, s.rollno);
fclose(fp);
Visual: Random Access
8. Integrating Structures and Files (Exam Focus)
Past Exam Question Analysis:
"Create a structure called
studentwithname,rollno, andcollegefor 10 students. Display the name of students who study at SoE."
Solution Code:
#include <stdio.h>
#include <string.h>
struct Student {
char name[50];
int rollno;
char college[50];
};
int main() {
struct Student students[10];
FILE *fp = fopen("students.txt", "w");
for (int i = 0; i < 10; i++) {
printf("Enter name, rollno, college: ");
scanf("%s %d %s", students[i].name, &students[i].rollno, students[i].college);
fprintf(fp, "%s %d %s\n", students[i].name, students[i].rollno, students[i].college);
}
fclose(fp);
// Read and filter
fp = fopen("students.txt", "r");
while (fscanf(fp, "%s %d %s", students[0].name, &students[0].rollno, students[0].college) != EOF) {
if (strcmp(students[0].college, "SoE") == 0) {
printf("SoE Student: %s %d\n", students[0].name, students[0].rollno);
}
}
fclose(fp);
return 0;
}
Visual: File After Input
Ramesh 101 SoE
Sita 102 SoCS
Hari 103 SoE
...
In the Real World
eSewa/Khalti Transactions:
- Idea Used: File handling (or databases) to store transaction logs.
- How: Every payment is written to a file (or database) with details like
user_id,amount,timestamp. When you check your history, the app reads from this file. - Code Analogy:
// Pseudocode for Khalti's transaction log FILE *fp = fopen("transactions.dat", "a"); fprintf(fp, "%s %d %.2f\n", user_id, amount, timestamp); fclose(fp);
Daraz Order Management:
- Idea Used: Binary files for storing order statuses (e.g., "Processing", "Shipped").
- How: Each order is a record in a binary file. When an order is updated (e.g., "Shipped"),
fseek()jumps to the order’s position and rewrites its status. - Real Scenario: If you track an order on Daraz, the system reads your order ID, uses
fseek()to locate it, and displays the latest status.
NTC Bill Generation:
- Idea Used: Sequential file reading to calculate bills.
- How: NTC stores consumption data for each customer in a text file. When generating a bill, it reads the file line-by-line (
fscanf), multiplies usage by rates, and writes the total to a new file. - Worked Example:
// Pseudocode for NTC bill calculation FILE *fp = fopen("consumption.txt", "r"); float units; while (fscanf(fp, "%f", &units) != EOF) { float bill = units * 5.0; // Rs. 5 per unit printf("Bill: Rs. %.2f\n", bill); } fclose(fp);
Exam Tip
File Modes Are Tricky:
"w"truncates the file;"a"appends. Mixing them up is a common mistake.- Exam Pitfall: Forgetting to check if
fopen()returnsNULL(loses marks).
Structures + Files = Full Marks:
- Always define a structure first, then use
fprintf/fscanforfread/fwrite. - Pro Tip: For binary files, use
sizeof(struct)to ensure correct byte counts.
- Always define a structure first, then use
Filtering Data:
- Questions often ask to display records matching a condition (e.g.,
college == "SoE"). - Use
while(fread(...) != EOF)orwhile(fscanf(...) != EOF)in loops.
- Questions often ask to display records matching a condition (e.g.,
Binary vs. Text:
- Binary (
"wb") is faster and exact; text ("w") is human-readable but slower. - Exam Clue: If the question mentions "exact storage," use binary mode.
- Binary (
Error Handling:
- Always include checks for
NULLafterfopen()and verify read/write operations. - Sample Answer Snippet:
if ((fp = fopen("data.txt", "r")) == NULL) { printf("Error: File not found.\n"); }
- Always include checks for
Past Exam Patterns:
- Part (a): Implement file operations with structures (e.g., store 10 records, filter).
- Part (b): Explain file modes or compare text/binary files (theory + table).
- Short Notes: Focus on
fopen()modes,fread/fwrite, and error handling.
Quick Revision Table
| Concept | Key Points | Example |
|---|---|---|
| File Modes | "r", "w", "a", "rb", "wb" |
fopen("file.txt", "a") |
| Structures in Files | Use fprintf/fscanf for text, fread/fwrite for binary. |
Store struct Student records. |
| Error Handling | Check fopen() return value and read/write status. |
if (fp == NULL) { ... } |
| Random Access | fseek(fp, offset, SEEK_SET) to jump to a record. |
Update a specific student. |
| Binary Files | Faster, exact storage (e.g., images, serialized data). | fwrite(&data, sizeof(data), 1, fp); |
Based on the PU BE Computer (PU) syllabus for Programming In C, unit 11.
Discussion
Loading…