Back to Lab HomeLab Exercise – 12

Experiment 12 – File Handling – Student Records

Aim

To implement file handling operations for storing and retrieving student records. Learn to write student data to a file and read it back using file operations in C programming. This experiment helps students understand data persistence, file I/O operations, and how to maintain data beyond program execution.

Through this experiment, students will learn to work with files, understand different file modes, implement error handling for file operations, and create programs that can store and retrieve data persistently.

Learning Outcomes

After completing this experiment, students will be able to:

  • Open files using fopen() with different modes (r, w, a, r+, w+, a+)
  • Write data to files using fprintf() or fwrite()
  • Read data from files using fscanf() or fread()
  • Check for file opening errors and handle them appropriately
  • Close files using fclose() to free resources
  • Understand the difference between text and binary file modes
  • Implement append mode to add records without overwriting
  • Create persistent data storage solutions

Algorithm

The algorithm for file handling involves opening, writing/reading, and closing files:

Write to File Algorithm:

  1. Declare FILE pointer: FILE *fp
  2. Open file: fp = fopen("filename.txt", "w" or "a")
  3. Check if fp == NULL (error opening)
  4. If error, display message and exit
  5. Input student data
  6. Write to file: fprintf(fp, format, data)
  7. Close file: fclose(fp)

Read from File Algorithm:

  1. Open file in read mode: fp = fopen("filename.txt", "r")
  2. Check for errors (fp == NULL)
  3. Loop while not end of file: while (!feof(fp)) orwhile (fscanf(...) != EOF)
  4. Read data: fscanf(fp, format, &variables)
  5. Display read data
  6. Close file

Procedure

  1. Include stdio.h and stdlib.h header files
  2. Define a structure Student with required fields
  3. For Writing to File:
    • Open file in write mode using fopen("filename.txt", "w")
    • Check if file opened successfully
    • Input student data
    • Write to file using fprintf() or fwrite()
    • Close file using fclose()
  4. For Reading from File:
    • Open file in read mode using fopen("filename.txt", "r")
    • Read data using fscanf() or fread()
    • Display the read data
    • Close file
  5. Handle file errors appropriately

Flowchart

Write to File:
  START
    ├─→ Declare: FILE *fp, struct Student s
    ├─→ fp = fopen("students.txt", "w")
    ├─→ IF (fp == NULL)
    │   │
    │   └─→ Display "Error opening file"
    │   └─→ EXIT
    │
    ├─→ Read student data
    ├─→ Write to file: fprintf(fp, ...)
    ├─→ fclose(fp)
    └─→ END

Read from File:
  START
    ├─→ Declare: FILE *fp, struct Student s
    ├─→ fp = fopen("students.txt", "r")
    ├─→ IF (fp == NULL)
    │   │
    │   └─→ Display "Error opening file"
    │   └─→ EXIT
    │
    ├─→ WHILE (!feof(fp))
    │   │
    │   ├─→ Read from file: fscanf(fp, ...)
    │   └─→ Display student data
    │
    ├─→ fclose(fp)
    └─→ END

Program Code

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

// Structure definition
struct Student {
    int rollNumber;
    char name[50];
    float marks[3];
    float total;
    float percentage;
};

// Function to write student record to file
void writeToFile(struct Student s) {
    FILE *fp;
    fp = fopen("students.txt", "a");  // "a" for append mode
    
    if (fp == NULL) {
        printf("Error opening file for writing!\n");
        return;
    }
    
    // Write student data to file
    fprintf(fp, "%d %s %.2f %.2f %.2f %.2f %.2f\n",
            s.rollNumber, s.name, s.marks[0], s.marks[1], 
            s.marks[2], s.total, s.percentage);
    
    fclose(fp);
    printf("Student record saved to file successfully!\n");
}

// Function to read all student records from file
void readFromFile() {
    FILE *fp;
    struct Student s;
    
    fp = fopen("students.txt", "r");  // "r" for read mode
    
    if (fp == NULL) {
        printf("Error opening file for reading!\n");
        printf("File may not exist. Please add some records first.\n");
        return;
    }
    
    printf("\n========== STUDENT RECORDS FROM FILE ==========\n");
    printf("%-10s %-20s %-8s %-8s %-8s %-8s %-10s\n",
           "Roll No", "Name", "Mark1", "Mark2", "Mark3", "Total", "Percentage");
    printf("-----------------------------------------------------------\n");
    
    // Read until end of file
    while (fscanf(fp, "%d %s %f %f %f %f %f",
                  &s.rollNumber, s.name, &s.marks[0], &s.marks[1],
                  &s.marks[2], &s.total, &s.percentage) != EOF) {
        
        printf("%-10d %-20s %-8.2f %-8.2f %-8.2f %-8.2f %-10.2f\n",
               s.rollNumber, s.name, s.marks[0], s.marks[1],
               s.marks[2], s.total, s.percentage);
    }
    
    fclose(fp);
}

int main() {
    struct Student s;
    int choice, n, i;
    
    do {
        printf("\n========== FILE HANDLING MENU ==========\n");
        printf("1. Add Student Record to File\n");
        printf("2. Display All Records from File\n");
        printf("3. Exit\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);
        
        switch(choice) {
            case 1:
                printf("\nEnter number of students to add: ");
                scanf("%d", &n);
                
                for (i = 0; i < n; i++) {
                    printf("\n--- Student %d ---\n", i + 1);
                    printf("Roll Number: ");
                    scanf("%d", &s.rollNumber);
                    
                    printf("Name: ");
                    scanf(" %[^\n]", s.name);
                    
                    printf("Enter marks for 3 subjects:\n");
                    printf("Subject 1: ");
                    scanf("%f", &s.marks[0]);
                    printf("Subject 2: ");
                    scanf("%f", &s.marks[1]);
                    printf("Subject 3: ");
                    scanf("%f", &s.marks[2]);
                    
                    s.total = s.marks[0] + s.marks[1] + s.marks[2];
                    s.percentage = (s.total / 300) * 100;
                    
                    writeToFile(s);
                }
                break;
                
            case 2:
                readFromFile();
                break;
                
            case 3:
                printf("Exiting program.\n");
                break;
                
            default:
                printf("Invalid choice!\n");
        }
    } while (choice != 3);
    
    return 0;
}

Sample Input and Output

Sample 1: Adding Records

Input:

========== FILE HANDLING MENU ==========
1. Add Student Record to File
2. Display All Records from File
3. Exit
Enter your choice: 1

Enter number of students to add: 2

--- Student 1 ---
Roll Number: 101
Name: Alice Johnson
Enter marks for 3 subjects:
Subject 1: 85
Subject 2: 90
Subject 3: 88
Student record saved to file successfully!

--- Student 2 ---
Roll Number: 102
Name: Bob Williams
Enter marks for 3 subjects:
Subject 1: 92
Subject 2: 87
Subject 3: 95
Student record saved to file successfully!

Sample 2: Reading Records

Input:

========== FILE HANDLING MENU ==========
1. Add Student Record to File
2. Display All Records from File
3. Exit
Enter your choice: 2

Output:

========== STUDENT RECORDS FROM FILE ==========
Roll No    Name                 Mark1    Mark2    Mark3    Total    Percentage
-----------------------------------------------------------
101        Alice Johnson        85.00    90.00    88.00    263.00   87.67
102        Bob Williams         92.00    87.00    95.00    274.00   91.33

Use Case / Real-world Relevance

File handling is essential for data persistence in applications:

  • Database Systems: Storing and retrieving data persistently
  • Configuration Files: Reading settings, preferences, and configuration data
  • Log Files: Recording application events, errors, and activities
  • Data Backup: Creating backups of important data
  • Report Generation: Writing reports, invoices, and documents to files
  • Data Import/Export: Transferring data between applications
  • System Administration: Managing system files, logs, and configurations
  • Application State: Saving game progress, user preferences, session data

Understanding file operations is crucial for building applications that need to store data beyond program execution. File handling enables data persistence, which is fundamental to most real-world applications. This knowledge forms the foundation for database systems, configuration management, logging, and data backup solutions.

Viva Questions

Q1: What are the different file modes in fopen() and when to use each?

"r" - read mode (file must exist), "w" - write mode (creates/overwrites), "a" - append mode (creates/appends), "r+" - read/write (file must exist), "w+" - read/write (creates/overwrites), "a+" - read/append (creates/appends). Use "r" for reading, "w" for writing new files, "a" for adding to existing files without losing data.

Q2: Why is it important to check if fopen() returns NULL?

fopen() returns NULL if file cannot be opened (file doesn't exist, permission denied, disk full, etc.). Using NULL pointer causes segmentation fault or undefined behavior. Always check: if (fp == NULL) . This prevents crashes and allows graceful error handling.

Q3: What is the difference between fprintf() and fwrite()?

fprintf() writes formatted text (human-readable), works with text files, converts data to text. fwrite() writes raw binary data, works with binary files, writes data as-is. Use fprintf for text files (readable), fwrite for binary files (efficient, exact representation). fprintf is slower but portable, fwrite is faster but platform-dependent.

Q4: Why should we always close files with fclose()?

fclose() flushes buffers (ensures all data is written), releases file handle (allows other programs to access), and frees system resources. Not closing files can cause data loss (buffered data not written), resource leaks (file handles not released), and prevent other programs from accessing the file. Operating systems limit number of open files per process.

Q5: What happens if we write to a file opened in read mode?

Attempting to write to a file opened in "r" mode causes undefined behavior or error. File opened in read mode is read-only. Use "r+" for read/write, "w" or "w+" for writing, or "a" for appending. Always use appropriate mode for intended operation to prevent errors and data corruption.

Q6: How do we detect end of file when reading?

Use feof(fp) which returns non-zero at end of file, or check return value offscanf() which returns EOF at end. Better approach:while (fscanf(fp, ...) != EOF) because feof() only returns true after attempting to read past end. Check fscanf return value immediately after reading, not before.

Q7: What is the difference between "w" and "a" modes?

"w" (write) mode creates new file or truncates existing file (deletes all content), starts writing from beginning. "a" (append) mode creates new file or opens existing file, writes at end (preserves existing content). Use "w" when you want to overwrite, "a" when you want to add to existing data without losing it.

Q8: Can we read and write to the same file in one program?

Yes, use "r+" (read/write, file must exist), "w+" (read/write, creates/overwrites), or "a+" (read/append, creates/appends). After writing, use fseek(fp, 0, SEEK_SET) to move to beginning before reading. Be careful with file position - reading and writing share the same file pointer position.

Related Links

🔹 Author: Dr. J. Siva Ramakrishna

🔹 Institution: Narayana Engineering College, Gudur

🔹 Last Updated: 9 January 2026