c

examples

examples.cšŸ”§
/**
 * =============================================================================
 *                          READING FILES - EXAMPLES
 * =============================================================================
 * 
 * This file demonstrates various methods for reading files in C:
 * - Character-by-character reading (fgetc, getc)
 * - Line-by-line reading (fgets)
 * - Formatted reading (fscanf)
 * - Binary reading (fread)
 * - Reading entire files
 * 
 * Compile: gcc -o examples examples.c -Wall -Wextra
 * Run:     ./examples
 * =============================================================================
 */

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

/* Function prototypes */
void example1_fgetc_basic(void);
void example2_fgetc_character_count(void);
void example3_fgets_basic(void);
void example4_fgets_remove_newline(void);
void example5_fscanf_numbers(void);
void example6_fscanf_structured_data(void);
void example7_fread_binary(void);
void example8_read_entire_file(void);
void example9_read_line_by_line_numbered(void);
void example10_read_csv_data(void);
void example11_read_key_value_config(void);
void example12_ungetc_demonstration(void);
void example13_eof_error_handling(void);
void example14_mixed_reading_methods(void);
void example15_performance_comparison(void);

void print_separator(const char *title);
void create_sample_files(void);
void cleanup_sample_files(void);

/* =============================================================================
 * MAIN FUNCTION
 * =============================================================================
 */
int main(void) {
    printf("╔══════════════════════════════════════════════════════════════════╗\n");
    printf("ā•‘              READING FILES - COMPREHENSIVE EXAMPLES              ā•‘\n");
    printf("ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•\n\n");
    
    create_sample_files();
    
    example1_fgetc_basic();
    example2_fgetc_character_count();
    example3_fgets_basic();
    example4_fgets_remove_newline();
    example5_fscanf_numbers();
    example6_fscanf_structured_data();
    example7_fread_binary();
    example8_read_entire_file();
    example9_read_line_by_line_numbered();
    example10_read_csv_data();
    example11_read_key_value_config();
    example12_ungetc_demonstration();
    example13_eof_error_handling();
    example14_mixed_reading_methods();
    example15_performance_comparison();
    
    cleanup_sample_files();
    
    printf("\n╔══════════════════════════════════════════════════════════════════╗\n");
    printf("ā•‘                    ALL EXAMPLES COMPLETED                         ā•‘\n");
    printf("ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•\n");
    
    return 0;
}

/* =============================================================================
 * HELPER FUNCTIONS
 * =============================================================================
 */
void print_separator(const char *title) {
    printf("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
    printf("  %s\n", title);
    printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n");
}

void create_sample_files(void) {
    FILE *fp;
    
    /* Create text.txt */
    fp = fopen("text.txt", "w");
    if (fp) {
        fprintf(fp, "Hello World!\n");
        fprintf(fp, "This is a sample text file.\n");
        fprintf(fp, "It contains multiple lines.\n");
        fprintf(fp, "Used for reading examples.\n");
        fclose(fp);
    }
    
    /* Create numbers.txt */
    fp = fopen("numbers.txt", "w");
    if (fp) {
        fprintf(fp, "10 20 30 40 50\n");
        fprintf(fp, "100 200 300\n");
        fprintf(fp, "1 2 3 4 5 6 7 8 9 10\n");
        fclose(fp);
    }
    
    /* Create employees.txt */
    fp = fopen("employees.txt", "w");
    if (fp) {
        fprintf(fp, "John 25 50000.00\n");
        fprintf(fp, "Alice 30 65000.50\n");
        fprintf(fp, "Bob 28 55000.75\n");
        fprintf(fp, "Carol 35 72000.00\n");
        fclose(fp);
    }
    
    /* Create data.csv */
    fp = fopen("data.csv", "w");
    if (fp) {
        fprintf(fp, "Name,Age,City,Salary\n");
        fprintf(fp, "John Smith,25,New York,50000.00\n");
        fprintf(fp, "Alice Johnson,30,Chicago,65000.50\n");
        fprintf(fp, "Bob Williams,28,Los Angeles,55000.75\n");
        fclose(fp);
    }
    
    /* Create config.ini */
    fp = fopen("config.ini", "w");
    if (fp) {
        fprintf(fp, "# Application Configuration\n");
        fprintf(fp, "username=admin\n");
        fprintf(fp, "password=secret123\n");
        fprintf(fp, "# Database settings\n");
        fprintf(fp, "database=myapp_db\n");
        fprintf(fp, "host=localhost\n");
        fprintf(fp, "port=5432\n");
        fclose(fp);
    }
    
    /* Create binary file */
    fp = fopen("data.bin", "wb");
    if (fp) {
        int numbers[] = {100, 200, 300, 400, 500};
        fwrite(numbers, sizeof(int), 5, fp);
        fclose(fp);
    }
}

void cleanup_sample_files(void) {
    remove("text.txt");
    remove("numbers.txt");
    remove("employees.txt");
    remove("data.csv");
    remove("config.ini");
    remove("data.bin");
}

/* =============================================================================
 * EXAMPLE 1: Basic fgetc() Usage
 * =============================================================================
 * Demonstrates reading a file character by character.
 */
void example1_fgetc_basic(void) {
    print_separator("EXAMPLE 1: Basic fgetc() Usage");
    
    FILE *fp = fopen("text.txt", "r");
    if (fp == NULL) {
        perror("Cannot open text.txt");
        return;
    }
    
    printf("Reading 'text.txt' character by character:\n");
    printf("─────────────────────────────────────────\n");
    
    /*
     * IMPORTANT: Use int, not char!
     * EOF is typically -1, and on some systems char is unsigned.
     * Using char could cause an infinite loop.
     */
    int ch;
    int char_count = 0;
    
    while ((ch = fgetc(fp)) != EOF) {
        putchar(ch);
        char_count++;
    }
    
    printf("─────────────────────────────────────────\n");
    printf("Total characters read: %d\n", char_count);
    
    fclose(fp);
}

/* =============================================================================
 * EXAMPLE 2: Character Counting with fgetc()
 * =============================================================================
 * Count different types of characters in a file.
 */
void example2_fgetc_character_count(void) {
    print_separator("EXAMPLE 2: Character Counting with fgetc()");
    
    FILE *fp = fopen("text.txt", "r");
    if (fp == NULL) {
        perror("Cannot open text.txt");
        return;
    }
    
    int ch;
    int letters = 0, digits = 0, spaces = 0, newlines = 0, others = 0;
    
    while ((ch = fgetc(fp)) != EOF) {
        if (isalpha(ch)) {
            letters++;
        } else if (isdigit(ch)) {
            digits++;
        } else if (ch == ' ') {
            spaces++;
        } else if (ch == '\n') {
            newlines++;
        } else {
            others++;
        }
    }
    
    printf("Character analysis of 'text.txt':\n\n");
    printf("ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”\n");
    printf("│ Character Type  │ Count │\n");
    printf("ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤\n");
    printf("│ Letters         │ %5d │\n", letters);
    printf("│ Digits          │ %5d │\n", digits);
    printf("│ Spaces          │ %5d │\n", spaces);
    printf("│ Newlines        │ %5d │\n", newlines);
    printf("│ Other           │ %5d │\n", others);
    printf("ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤\n");
    printf("│ Total           │ %5d │\n", letters + digits + spaces + newlines + others);
    printf("ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜\n");
    
    fclose(fp);
}

/* =============================================================================
 * EXAMPLE 3: Basic fgets() Usage
 * =============================================================================
 * Demonstrates reading lines from a file.
 */
void example3_fgets_basic(void) {
    print_separator("EXAMPLE 3: Basic fgets() Usage");
    
    FILE *fp = fopen("text.txt", "r");
    if (fp == NULL) {
        perror("Cannot open text.txt");
        return;
    }
    
    printf("Reading 'text.txt' line by line with fgets():\n\n");
    
    /*
     * fgets() reads up to n-1 characters or until newline.
     * It includes the newline in the buffer.
     * Returns NULL on EOF or error.
     */
    char buffer[256];
    int line_num = 0;
    
    while (fgets(buffer, sizeof(buffer), fp) != NULL) {
        line_num++;
        printf("Line %d: %s", line_num, buffer);
        /* Note: buffer includes \n, so no extra newline needed */
    }
    
    printf("\nTotal lines: %d\n", line_num);
    
    fclose(fp);
}

/* =============================================================================
 * EXAMPLE 4: Removing Newline from fgets()
 * =============================================================================
 * Shows different methods to remove trailing newline.
 */
void example4_fgets_remove_newline(void) {
    print_separator("EXAMPLE 4: Removing Newline from fgets()");
    
    FILE *fp = fopen("text.txt", "r");
    if (fp == NULL) {
        perror("Cannot open text.txt");
        return;
    }
    
    char buffer[256];
    int line_num = 0;
    
    printf("Reading lines with newline removed:\n\n");
    
    while (fgets(buffer, sizeof(buffer), fp) != NULL) {
        line_num++;
        
        /*
         * Three methods to remove newline:
         */
        
        /* Method 1: Using strcspn (recommended - concise) */
        buffer[strcspn(buffer, "\n")] = '\0';
        
        /* Method 2: Using strlen
        size_t len = strlen(buffer);
        if (len > 0 && buffer[len-1] == '\n') {
            buffer[len-1] = '\0';
        }
        */
        
        /* Method 3: Using strchr
        char *newline = strchr(buffer, '\n');
        if (newline) *newline = '\0';
        */
        
        /* Now buffer doesn't have newline */
        printf("Line %d: [%s]\n", line_num, buffer);
    }
    
    printf("\nNote: Brackets show exact string boundaries (no trailing newline).\n");
    
    fclose(fp);
}

/* =============================================================================
 * EXAMPLE 5: Reading Numbers with fscanf()
 * =============================================================================
 * Demonstrates formatted reading of numeric data.
 */
void example5_fscanf_numbers(void) {
    print_separator("EXAMPLE 5: Reading Numbers with fscanf()");
    
    FILE *fp = fopen("numbers.txt", "r");
    if (fp == NULL) {
        perror("Cannot open numbers.txt");
        return;
    }
    
    printf("Reading integers from 'numbers.txt':\n\n");
    
    /*
     * fscanf() returns the number of items successfully matched.
     * Returns EOF if end-of-file is reached before any conversion.
     */
    int num;
    int count = 0;
    int sum = 0;
    
    printf("Numbers found: ");
    
    while (fscanf(fp, "%d", &num) == 1) {
        printf("%d ", num);
        sum += num;
        count++;
    }
    
    printf("\n\nStatistics:\n");
    printf("  Count: %d\n", count);
    printf("  Sum: %d\n", sum);
    printf("  Average: %.2f\n", count > 0 ? (float)sum / count : 0.0f);
    
    fclose(fp);
}

/* =============================================================================
 * EXAMPLE 6: Reading Structured Data with fscanf()
 * =============================================================================
 * Demonstrates reading records with multiple fields.
 */
void example6_fscanf_structured_data(void) {
    print_separator("EXAMPLE 6: Reading Structured Data with fscanf()");
    
    FILE *fp = fopen("employees.txt", "r");
    if (fp == NULL) {
        perror("Cannot open employees.txt");
        return;
    }
    
    printf("Reading employee records from 'employees.txt':\n\n");
    printf("ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”\n");
    printf("│ Name           │ Age │ Salary      │\n");
    printf("ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤\n");
    
    /*
     * Format: name age salary
     * %49s limits string to 49 chars (buffer is 50)
     */
    char name[50];
    int age;
    float salary;
    
    /* fscanf returns number of items matched */
    while (fscanf(fp, "%49s %d %f", name, &age, &salary) == 3) {
        printf("│ %-14s │ %3d │ %11.2f │\n", name, age, salary);
    }
    
    printf("ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜\n");
    
    fclose(fp);
}

/* =============================================================================
 * EXAMPLE 7: Reading Binary Data with fread()
 * =============================================================================
 * Demonstrates reading binary file contents.
 */
void example7_fread_binary(void) {
    print_separator("EXAMPLE 7: Reading Binary Data with fread()");
    
    /* Open in binary mode "rb" */
    FILE *fp = fopen("data.bin", "rb");
    if (fp == NULL) {
        perror("Cannot open data.bin");
        return;
    }
    
    printf("Reading integers from binary file 'data.bin':\n\n");
    
    /*
     * fread() syntax:
     *   size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
     * 
     * Returns: Number of complete items successfully read
     */
    int numbers[10];
    size_t items_read = fread(numbers, sizeof(int), 10, fp);
    
    printf("Items read: %zu\n", items_read);
    printf("Values: ");
    
    for (size_t i = 0; i < items_read; i++) {
        printf("%d ", numbers[i]);
    }
    printf("\n");
    
    /* Check why reading stopped */
    if (feof(fp)) {
        printf("\nReached end of file.\n");
    } else if (ferror(fp)) {
        printf("\nError occurred while reading.\n");
    }
    
    fclose(fp);
}

/* =============================================================================
 * EXAMPLE 8: Reading Entire File into Memory
 * =============================================================================
 * Demonstrates loading complete file contents.
 */
void example8_read_entire_file(void) {
    print_separator("EXAMPLE 8: Reading Entire File into Memory");
    
    FILE *fp = fopen("text.txt", "rb");
    if (fp == NULL) {
        perror("Cannot open text.txt");
        return;
    }
    
    /* Step 1: Get file size */
    fseek(fp, 0, SEEK_END);
    long file_size = ftell(fp);
    rewind(fp);  /* Go back to beginning */
    
    printf("File size: %ld bytes\n\n", file_size);
    
    /* Step 2: Allocate buffer */
    char *buffer = (char *)malloc(file_size + 1);  /* +1 for null terminator */
    if (buffer == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        fclose(fp);
        return;
    }
    
    /* Step 3: Read entire file */
    size_t bytes_read = fread(buffer, 1, file_size, fp);
    buffer[bytes_read] = '\0';  /* Null terminate for string operations */
    
    printf("Bytes read: %zu\n\n", bytes_read);
    printf("File contents:\n");
    printf("─────────────────────────────────────────\n");
    printf("%s", buffer);
    printf("─────────────────────────────────────────\n");
    
    /* Step 4: Cleanup */
    free(buffer);
    fclose(fp);
}

/* =============================================================================
 * EXAMPLE 9: Line-by-Line Reading with Line Numbers
 * =============================================================================
 * A simple file viewer with line numbers.
 */
void example9_read_line_by_line_numbered(void) {
    print_separator("EXAMPLE 9: Line-by-Line with Line Numbers");
    
    FILE *fp = fopen("text.txt", "r");
    if (fp == NULL) {
        perror("Cannot open text.txt");
        return;
    }
    
    printf("File Viewer: text.txt\n");
    printf("════════════════════════════════════════════════\n");
    
    char line[256];
    int line_num = 0;
    
    while (fgets(line, sizeof(line), fp) != NULL) {
        line_num++;
        
        /* Remove newline for consistent formatting */
        line[strcspn(line, "\n")] = '\0';
        
        /* Print with line number (right-aligned, 4 digits) */
        printf("%4d │ %s\n", line_num, line);
    }
    
    printf("════════════════════════════════════════════════\n");
    printf("Total: %d lines\n", line_num);
    
    fclose(fp);
}

/* =============================================================================
 * EXAMPLE 10: Reading CSV Data
 * =============================================================================
 * Demonstrates parsing comma-separated values.
 */
void example10_read_csv_data(void) {
    print_separator("EXAMPLE 10: Reading CSV Data");
    
    FILE *fp = fopen("data.csv", "r");
    if (fp == NULL) {
        perror("Cannot open data.csv");
        return;
    }
    
    printf("Parsing 'data.csv':\n\n");
    
    char line[256];
    int row = 0;
    
    while (fgets(line, sizeof(line), fp) != NULL) {
        row++;
        line[strcspn(line, "\n")] = '\0';
        
        if (row == 1) {
            /* Header row */
            printf("Header: %s\n", line);
            printf("────────────────────────────────────────────────\n");
            continue;
        }
        
        /* Parse data row using sscanf with scansets */
        char name[50], city[50];
        int age;
        float salary;
        
        /*
         * %[^,] reads until comma
         * , matches and consumes a comma
         */
        if (sscanf(line, "%49[^,],%d,%49[^,],%f", 
                   name, &age, city, &salary) == 4) {
            printf("Record %d:\n", row - 1);
            printf("  Name:   %s\n", name);
            printf("  Age:    %d\n", age);
            printf("  City:   %s\n", city);
            printf("  Salary: $%.2f\n\n", salary);
        }
    }
    
    fclose(fp);
}

/* =============================================================================
 * EXAMPLE 11: Reading Key-Value Configuration
 * =============================================================================
 * Demonstrates parsing configuration files.
 */
void example11_read_key_value_config(void) {
    print_separator("EXAMPLE 11: Reading Key-Value Configuration");
    
    FILE *fp = fopen("config.ini", "r");
    if (fp == NULL) {
        perror("Cannot open config.ini");
        return;
    }
    
    printf("Parsing 'config.ini':\n\n");
    printf("ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”\n");
    printf("│ Key            │ Value                      │\n");
    printf("ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤\n");
    
    char line[256];
    char key[128], value[128];
    
    while (fgets(line, sizeof(line), fp) != NULL) {
        /* Skip comments and empty lines */
        if (line[0] == '#' || line[0] == '\n' || line[0] == ';') {
            continue;
        }
        
        /* Parse key=value format */
        if (sscanf(line, "%127[^=]=%127[^\n]", key, value) == 2) {
            printf("│ %-14s │ %-26s │\n", key, value);
        }
    }
    
    printf("ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜\n");
    
    fclose(fp);
}

/* =============================================================================
 * EXAMPLE 12: ungetc() Demonstration
 * =============================================================================
 * Shows how to push characters back to the stream.
 */
void example12_ungetc_demonstration(void) {
    print_separator("EXAMPLE 12: ungetc() Demonstration");
    
    FILE *fp = fopen("numbers.txt", "r");
    if (fp == NULL) {
        perror("Cannot open numbers.txt");
        return;
    }
    
    printf("Using ungetc() to peek at next character:\n\n");
    
    /*
     * ungetc() pushes a character back onto the input stream.
     * Useful for peeking ahead without consuming the character.
     */
    
    int ch;
    int token_count = 0;
    
    printf("Processing 'numbers.txt':\n");
    
    while ((ch = fgetc(fp)) != EOF) {
        if (isdigit(ch)) {
            /* Found start of a number - push it back */
            ungetc(ch, fp);
            
            /* Now read the complete number */
            int num;
            fscanf(fp, "%d", &num);
            
            token_count++;
            printf("  Found number: %d\n", num);
        }
        /* Skip whitespace and other characters */
    }
    
    printf("\nTotal numbers found: %d\n", token_count);
    
    fclose(fp);
}

/* =============================================================================
 * EXAMPLE 13: EOF and Error Handling
 * =============================================================================
 * Demonstrates proper EOF detection and error checking.
 */
void example13_eof_error_handling(void) {
    print_separator("EXAMPLE 13: EOF and Error Handling");
    
    FILE *fp = fopen("text.txt", "r");
    if (fp == NULL) {
        perror("Cannot open text.txt");
        return;
    }
    
    printf("Demonstrating proper EOF and error handling:\n\n");
    
    /*
     * WRONG way (common mistake):
     * while (!feof(fp)) {
     *     ch = fgetc(fp);
     *     // ch might be EOF here!
     * }
     * 
     * CORRECT way:
     * while ((ch = fgetc(fp)) != EOF) {
     *     // ch is valid
     * }
     * // Then check feof() and ferror()
     */
    
    int ch;
    int count = 0;
    
    printf("Reading file correctly:\n");
    
    /* CORRECT pattern */
    while ((ch = fgetc(fp)) != EOF) {
        count++;
        /* Character is valid here */
    }
    
    /* After loop, determine WHY it ended */
    printf("  Read %d characters\n\n", count);
    
    if (feof(fp)) {
        printf("Termination reason: End of file (feof() = true)\n");
        printf("  This is normal - file was completely read.\n");
    }
    
    if (ferror(fp)) {
        printf("Termination reason: Error occurred (ferror() = true)\n");
        printf("  Error: %s\n", strerror(errno));
        clearerr(fp);  /* Clear the error indicator */
    }
    
    /* Demonstrate clearerr */
    printf("\nAfter clearerr():\n");
    printf("  feof(): %s\n", feof(fp) ? "true" : "false");
    printf("  ferror(): %s\n", ferror(fp) ? "true" : "false");
    
    fclose(fp);
}

/* =============================================================================
 * EXAMPLE 14: Mixed Reading Methods
 * =============================================================================
 * Shows when to use each reading method.
 */
void example14_mixed_reading_methods(void) {
    print_separator("EXAMPLE 14: Mixed Reading Methods");
    
    printf("When to use each reading method:\n\n");
    
    printf("ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”\n");
    printf("│ Function    │ Best Use Case                                 │\n");
    printf("ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤\n");
    printf("│ fgetc()     │ Character-by-character processing, lexing     │\n");
    printf("│ fgets()     │ Line-oriented text, configuration files       │\n");
    printf("│ fscanf()    │ Formatted data with known structure           │\n");
    printf("│ fread()     │ Binary files, bulk data, structures           │\n");
    printf("│ getline()   │ Lines of unknown length (POSIX only)          │\n");
    printf("ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜\n\n");
    
    /* Demonstrate each on the same data */
    printf("Reading same file with different methods:\n\n");
    
    /* Create a simple test file */
    FILE *fp = fopen("test_mixed.txt", "w");
    if (fp) {
        fprintf(fp, "42 Hello World\n");
        fclose(fp);
    }
    
    /* Method 1: fgetc */
    printf("1. Using fgetc():\n   Characters: ");
    fp = fopen("test_mixed.txt", "r");
    if (fp) {
        int ch;
        while ((ch = fgetc(fp)) != EOF) {
            if (ch == '\n') printf("\\n");
            else printf("%c", ch);
        }
        printf("\n\n");
        fclose(fp);
    }
    
    /* Method 2: fgets */
    printf("2. Using fgets():\n   Line: ");
    fp = fopen("test_mixed.txt", "r");
    if (fp) {
        char buffer[100];
        if (fgets(buffer, sizeof(buffer), fp)) {
            buffer[strcspn(buffer, "\n")] = '\0';
            printf("\"%s\"\n\n", buffer);
        }
        fclose(fp);
    }
    
    /* Method 3: fscanf */
    printf("3. Using fscanf():\n");
    fp = fopen("test_mixed.txt", "r");
    if (fp) {
        int num;
        char word1[20], word2[20];
        if (fscanf(fp, "%d %19s %19s", &num, word1, word2) == 3) {
            printf("   Number: %d\n", num);
            printf("   Word 1: %s\n", word1);
            printf("   Word 2: %s\n\n", word2);
        }
        fclose(fp);
    }
    
    /* Method 4: fread */
    printf("4. Using fread():\n   Raw bytes: ");
    fp = fopen("test_mixed.txt", "rb");
    if (fp) {
        char buffer[100];
        size_t bytes = fread(buffer, 1, sizeof(buffer) - 1, fp);
        buffer[bytes] = '\0';
        for (size_t i = 0; i < bytes; i++) {
            if (buffer[i] == '\n') printf("\\n");
            else printf("%c", buffer[i]);
        }
        printf(" (%zu bytes)\n", bytes);
        fclose(fp);
    }
    
    remove("test_mixed.txt");
}

/* =============================================================================
 * EXAMPLE 15: Performance Comparison
 * =============================================================================
 * Compares reading performance of different methods.
 */
void example15_performance_comparison(void) {
    print_separator("EXAMPLE 15: Performance Comparison");
    
    printf("Creating a larger test file...\n");
    
    /* Create a larger test file */
    const char *filename = "perf_test.txt";
    FILE *fp = fopen(filename, "w");
    if (fp) {
        for (int i = 0; i < 10000; i++) {
            fprintf(fp, "Line %d: This is a sample line for performance testing.\n", i);
        }
        fclose(fp);
    }
    
    /* Get file size */
    fp = fopen(filename, "rb");
    fseek(fp, 0, SEEK_END);
    long file_size = ftell(fp);
    fclose(fp);
    
    printf("File size: %ld bytes (10,000 lines)\n\n", file_size);
    
    printf("Performance characteristics (relative):\n\n");
    printf("ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”\n");
    printf("│ Method            │ Speed        │ Memory       │\n");
    printf("ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤\n");
    printf("│ fgetc() char-by   │ Slowest      │ Minimal      │\n");
    printf("│ fgets() line-by   │ Medium       │ Buffer size  │\n");
    printf("│ fread() block     │ Fast         │ Block size   │\n");
    printf("│ fread() whole     │ Fastest      │ File size    │\n");
    printf("ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜\n\n");
    
    /* Demonstrate each method (showing byte counts) */
    long bytes;
    int ch;
    char buffer[4096];
    
    /* fgetc */
    bytes = 0;
    fp = fopen(filename, "r");
    while ((ch = fgetc(fp)) != EOF) bytes++;
    fclose(fp);
    printf("fgetc():  Read %ld characters\n", bytes);
    
    /* fgets */
    bytes = 0;
    int lines = 0;
    fp = fopen(filename, "r");
    while (fgets(buffer, sizeof(buffer), fp)) {
        bytes += strlen(buffer);
        lines++;
    }
    fclose(fp);
    printf("fgets():  Read %ld bytes in %d lines\n", bytes, lines);
    
    /* fread block */
    bytes = 0;
    size_t read;
    fp = fopen(filename, "rb");
    while ((read = fread(buffer, 1, sizeof(buffer), fp)) > 0) {
        bytes += read;
    }
    fclose(fp);
    printf("fread():  Read %ld bytes in blocks of %zu\n", bytes, sizeof(buffer));
    
    printf("\nRecommendations:\n");
    printf("  • Use fgetc() for lexical analysis, tokenizing\n");
    printf("  • Use fgets() for config files, line-oriented text\n");
    printf("  • Use fread() for binary files, maximum performance\n");
    printf("  • Match buffer size to expected line/data length\n");
    
    remove(filename);
}
Examples - C Programming Tutorial | DeepML