Day 12: File Handling Basics#

Overview#

So far, all our data disappears when the program ends. Today we’ll learn how to save data to files and read data from files, making our programs persistent.

What We’ll Learn Today#

  • File concepts and modes
  • Opening and closing files
  • Reading from files
  • Writing to files
  • Error handling with files
  • Different file I/O functions
  • Working with structured data in files

File Handling in C#

C provides functions for file operations in <stdio.h>:

The FILE Pointer#

FILE* file = fopen("filename.txt", "r");
  • FILE*: Pointer to file structure
  • Contains file information and position

Opening Files: fopen()#

FILE* fopen(const char* filename, const char* mode);

File Modes#

ModeMeaningCreates File?
"r"ReadNo (error if not exists)
"w"Write (overwrites)Yes
"a"Append (add to end)Yes
"r+"Read and writeNo
"w+"Write and read (overwrites)Yes
"a+"Append and readYes

Basic Example#

#include <stdio.h>

int main() {
    FILE* file = fopen("myfile.txt", "r");

    // Check if file opened successfully
    if (file == NULL) {
        printf("Error: Could not open file\n");
        return 1;
    }

    // Use file here

    fclose(file);  // Close file when done

    return 0;
}

Closing Files: fclose()#

Always close files after using them:

fclose(file);

Why? Ensures all data is written and resources are freed.

#include <stdio.h>

int main() {
    FILE* file = fopen("myfile.txt", "w");

    if (file == NULL) {
        printf("Error opening file\n");
        return 1;
    }

    fprintf(file, "Hello, World!\n");

    fclose(file);  // Always close

    return 0;
}

Writing to Files#

fprintf() - Formatted Writing#

Like printf() but writes to a file:

fprintf(file, "format", arguments);

Example: Write Text to File#

#include <stdio.h>

int main() {
    FILE* file = fopen("output.txt", "w");

    if (file == NULL) {
        printf("Cannot create file\n");
        return 1;
    }

    fprintf(file, "Hello, World!\n");
    fprintf(file, "This is line 2\n");
    fprintf(file, "Number: %d\n", 42);
    fprintf(file, "Float: %.2f\n", 3.14159);

    fclose(file);
    printf("File written successfully\n");

    return 0;
}

Creates file output.txt with:

Hello, World!
This is line 2
Number: 42
Float: 3.14

Example: Write Multiple Records#

#include <stdio.h>

int main() {
    FILE* file = fopen("students.txt", "w");

    if (file == NULL) {
        printf("Error opening file\n");
        return 1;
    }

    // Write header
    fprintf(file, "ID\tName\t\tGPA\n");
    fprintf(file, "================================\n");

    // Write student records
    fprintf(file, "101\tAlice\t\t3.8\n");
    fprintf(file, "102\tBob\t\t3.5\n");
    fprintf(file, "103\tCharlie\t\t3.9\n");

    fclose(file);
    printf("Student records saved\n");

    return 0;
}

Reading from Files#

fgets() - Read Line by Line#

char* fgets(char* str, int size, FILE* stream);
  • str: Buffer to store the line
  • size: Maximum characters to read (including \0)
  • stream: File to read from

Example: Read Text File#

#include <stdio.h>

int main() {
    FILE* file = fopen("input.txt", "r");

    if (file == NULL) {
        printf("Cannot open file\n");
        return 1;
    }

    char line[100];

    while (fgets(line, sizeof(line), file) != NULL) {
        printf("%s", line);  // line already has \n
    }

    fclose(file);

    return 0;
}

fscanf() - Formatted Reading#

Like scanf() but reads from a file:

fscanf(file, "format", &variables);

Example: Read Structured Data#

#include <stdio.h>

typedef struct {
    int id;
    char name[50];
    float gpa;
} Student;

int main() {
    FILE* file = fopen("students.txt", "r");

    if (file == NULL) {
        printf("Cannot open file\n");
        return 1;
    }

    Student student;

    // Read students from file
    while (fscanf(file, "%d %s %f", &student.id, student.name, &student.gpa) == 3) {
        printf("ID: %d, Name: %s, GPA: %.2f\n", student.id, student.name, student.gpa);
    }

    fclose(file);

    return 0;
}

fgetc() - Read Single Character#

int ch = fgetc(file);  // Returns EOF if end of file

Example: Count Characters#

#include <stdio.h>

int main() {
    FILE* file = fopen("data.txt", "r");

    if (file == NULL) {
        printf("Error opening file\n");
        return 1;
    }

    int count = 0;
    int ch;

    while ((ch = fgetc(file)) != EOF) {
        count++;
    }

    printf("Total characters: %d\n", count);

    fclose(file);

    return 0;
}

Practical Example: Student Record Manager#

Writing Records#

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

typedef struct {
    int id;
    char name[50];
    float marks[3];
    float gpa;
} Student;

int main() {
    FILE* file = fopen("records.txt", "w");

    if (file == NULL) {
        printf("Cannot create file\n");
        return 1;
    }

    int n;
    printf("How many students? ");
    scanf("%d", &n);
    getchar();  // Consume newline

    for (int i = 0; i < n; i++) {
        Student s;

        printf("\nStudent %d:\n", i + 1);
        printf("ID: ");
        scanf("%d", &s.id);

        printf("Name: ");
        scanf("%s", s.name);

        printf("Marks (3 subjects): ");
        scanf("%f %f %f", &s.marks[0], &s.marks[1], &s.marks[2]);

        s.gpa = (s.marks[0] + s.marks[1] + s.marks[2]) / 3.0;

        fprintf(file, "%d %s %.2f %.2f %.2f %.2f\n",
                s.id, s.name, s.marks[0], s.marks[1], s.marks[2], s.gpa);
    }

    fclose(file);
    printf("\nRecords saved to records.txt\n");

    return 0;
}

Reading Records#

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

typedef struct {
    int id;
    char name[50];
    float marks[3];
    float gpa;
} Student;

int main() {
    FILE* file = fopen("records.txt", "r");

    if (file == NULL) {
        printf("Cannot open file\n");
        return 1;
    }

    Student s;

    printf("=== Student Records ===\n");

    while (fscanf(file, "%d %s %f %f %f %f",
                  &s.id, s.name, &s.marks[0],
                  &s.marks[1], &s.marks[2], &s.gpa) == 6) {

        printf("\nID: %d\n", s.id);
        printf("Name: %s\n", s.name);
        printf("Marks: %.2f, %.2f, %.2f\n", s.marks[0], s.marks[1], s.marks[2]);
        printf("GPA: %.2f\n", s.gpa);
    }

    fclose(file);

    return 0;
}

File Position Functions#

feof() - Check End of File#

if (feof(file)) {
    printf("End of file reached\n");
}

ftell() - Get Current Position#

long position = ftell(file);

fseek() - Move File Position#

fseek(file, offset, whence);
  • offset: Bytes to move
  • whence: Reference point
    • SEEK_SET: Beginning of file
    • SEEK_CUR: Current position
    • SEEK_END: End of file

Example: Go to End of File#

fseek(file, 0, SEEK_END);
long size = ftell(file);
printf("File size: %ld bytes\n", size);

Error Handling with Files#

Check File Opening#

FILE* file = fopen("data.txt", "r");

if (file == NULL) {
    perror("Error opening file");  // Prints system error message
    return 1;
}

Check Read/Write Operations#

if (fprintf(file, "data") < 0) {
    printf("Error writing to file\n");
}

if (fscanf(file, "%d", &value) != 1) {
    printf("Error reading from file\n");
}

Appending to Files#

Add data to the end of existing file:

#include <stdio.h>

int main() {
    FILE* file = fopen("log.txt", "a");  // Append mode

    if (file == NULL) {
        printf("Cannot open file\n");
        return 1;
    }

    fprintf(file, "New log entry\n");

    fclose(file);

    return 0;
}

Practice Exercises#

Exercise 1: Simple Note Maker#

Write a program that:

  • Writes 5 lines of user input to a file
  • Reads and displays the file

Exercise 2: Grade Calculator#

Write a program that:

  • Reads student records from file
  • Calculates grades
  • Writes results to new file

Exercise 3: File Statistics#

Write a program that:

  • Reads a text file
  • Counts lines, words, characters
  • Displays statistics

Summary#

✅ Understood file concepts and modes
✅ Opened and closed files properly
✅ Read from files using fgets() and fscanf()
✅ Wrote to files using fprintf()
✅ Handled file errors
✅ Worked with structured data in files
✅ Used file position functions

Key Points to Remember#

  1. Always check if fopen() returned NULL
  2. Always fclose() files when done
  3. Use "w" to overwrite, "a" to append
  4. Use fprintf()/fscanf() like printf()/scanf()
  5. Check return values of file operations
  6. Use fgets() for line-by-line reading
  7. Use feof() to check end of file

Next Steps#

Tomorrow we’ll learn about error handling and debugging - essential skills for professional programming!

→ Continue to Day 13

← Back to Day 11