C Read Files

Learn how to read data from files in C programming

📖 Reading Files in C

File reading in C allows you to retrieve stored data using functions like fscanf(), fgets(), and fread(). You can read text, numbers, and binary data from files for processing and displaying information in your programs.


#include <stdio.h>

int main() {
    FILE *file = fopen("data.txt", "r");
    char buffer[100];
    fgets(buffer, 100, file);
    printf("%s", buffer);
    fclose(file);
    return 0;
}
                                    

File Reading Functions

🔍

fscanf()

Read formatted data from files

fscanf(file, "%d %s", #, str);
📄

fgets()

Read strings/lines from files

fgets(buffer, size, file);
🔤

fgetc()

Read single characters from files

char ch = fgetc(file);
💾

fread()

Read binary data from files

fread(&data, sizeof(int), 1, file);

🔹 Reading Text with fscanf()

The fscanf() function reads and automatically parses formatted data from files into variables. It works identically to scanf() but reads from files instead of standard input, enabling automatic type conversion and parsing. Specify format strings to describe expected data structure, and fscanf() extracts and converts values accordingly. Always check fscanf() return values to verify how many values were successfully read, handle incomplete reads gracefully, and ensure format specifiers match actual file content.

#include <stdio.h>

int main() {
    FILE *file;
    char name[50];
    int age;
    float salary;
    
    file = fopen("employee.txt", "r");
    
    if (file != NULL) {
        // Skip the header line
        fscanf(file, "%*[^\n]\n");
        
        // Read formatted data
        fscanf(file, "Name: %s\n", name);
        fscanf(file, "Age: %d\n", &age);
        fscanf(file, "Salary: %f\n", &salary);
        
        printf("Employee Data:\n");
        printf("Name: %s\n", name);
        printf("Age: %d\n", age);
        printf("Salary: %.2f\n", salary);
        
        fclose(file);
    } else {
        printf("Error opening file!\n");
    }
    
    return 0;
}

Output:

Employee Data:
Name: John
Age: 25
Salary: 50000.50

🔹 Reading Lines with fgets()

The fgets() function safely reads entire lines from files with built-in buffer overflow protection. Unlike gets(), fgets() accepts a maximum size parameter preventing buffer overflows and security vulnerabilities. It reads characters until finding a newline or reaching the maximum size, null-terminating the string automatically. Use fgets() for all line-based file reading, remove trailing newlines if necessary, and implement error checking for incomplete reads due to file errors.

#include <stdio.h>

int main() {
    FILE *file;
    char line[100];
    
    file = fopen("story.txt", "r");
    
    if (file != NULL) {
        printf("Reading story from file:\n");
        printf("========================\n");
        
        // Read line by line
        while (fgets(line, sizeof(line), file) != NULL) {
            printf("%s", line);
        }
        
        fclose(file);
    } else {
        printf("Error opening file!\n");
    }
    
    return 0;
}

Output:

Reading story from file:
========================
Once upon a time...
There was a programmer learning C.
They mastered file handling!

🔹 Reading Characters with fgetc()

The fgetc() function reads files character-by-character, useful for processing individual characters and building custom parsing logic. Returns the character code as an integer or EOF when reaching file end or encountering errors. This approach works for analyzing file content byte-by-byte, implementing custom parsing algorithms, or processing text with specific character-level requirements. Always distinguish between normal EOF and error conditions using ferror() for robust character-by-character processing.

#include <stdio.h>

int main() {
    FILE *file;
    char ch;
    int charCount = 0;
    
    file = fopen("chars.txt", "r");
    
    if (file != NULL) {
        printf("File contents: ");
        
        // Read character by character
        while ((ch = fgetc(file)) != EOF) {
            printf("%c", ch);
            charCount++;
        }
        
        printf("\nTotal characters read: %d\n", charCount);
        fclose(file);
    }
    
    return 0;
}

Output:

File contents: HELLO
Total characters read: 6

🔹 Reading with Error Checking

Always implement comprehensive error checking when reading files to handle failures and edge cases appropriately. Check return values of reading functions to verify successful operations, distinguish between EOF conditions and actual errors, use ferror() to detect read errors, and clear error flags when necessary. Implement informative error messages explaining what went wrong, handle incomplete reads gracefully, and design recovery mechanisms so programs continue operating safely even when read operations fail unexpectedly.

#include <stdio.h>

int main() {
    FILE *file;
    char buffer[100];
    
    file = fopen("data.txt", "r");
    
    if (file == NULL) {
        printf("Error: Cannot open file for reading!\n");
        return 1;
    }
    
    printf("File opened successfully!\n");
    
    // Check if file is empty
    if (fgets(buffer, sizeof(buffer), file) != NULL) {
        printf("First line: %s", buffer);
    } else {
        printf("File is empty or error reading!\n");
    }
    
    // Check for end of file
    if (feof(file)) {
        printf("Reached end of file.\n");
    }
    
    fclose(file);
    return 0;
}

Output:

File opened successfully!
First line: Hello, World!
Reached end of file.

🔹 Reading Student Records

Reading structured data like student records from files requires parsing multiple fields and storing them appropriately. Use fscanf() with appropriate format strings to extract names, identification numbers, grades, and other student information from formatted files. Define structures that mirror file layout, allocate storage for records, and handle reading errors appropriately. This approach demonstrates practical file I/O usage in real-world applications involving database-like operations and structured data persistence.

#include <stdio.h>

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

int main() {
    FILE *file;
    struct Student student;
    
    file = fopen("students.txt", "r");
    
    if (file != NULL) {
        // Skip header lines
        fscanf(file, "%*[^\n]\n%*[^\n]\n");
        
        printf("Student Records:\n");
        printf("================\n");
        
        // Read student records
        while (fscanf(file, "ID: %d, Name: %s, Grade: %f\n", 
                      &student.id, student.name, &student.grade) == 3) {
            printf("ID: %d\n", student.id);
            printf("Name: %s\n", student.name);
            printf("Grade: %.1f\n\n", student.grade);
        }
        
        fclose(file);
    }
    
    return 0;
}

Output:

Student Records:
================
ID: 1
Name: Alice
Grade: 85.5

ID: 2
Name: Bob
Grade: 92.0

ID: 3
Name: Charlie
Grade: 78.5

🧠 Test Your Knowledge

Which function reads a complete line from a file?