c
examples
examples.cš§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);
}