File I/O Operations in C: Text, Binary, Character, and Structured Data Handling
Writing and Reading Formatetd Text Files
#include <stdio.h>
#define TITLE_LEN 80
#define AUTHOR_LEN 80
#define CAPACITY 100
typedef struct {
char title[TITLE_LEN];
char writer[AUTHOR_LEN];
} Publication;
void store_text();
void load_text();
int main() {
store_text();
load_text();
return 0;
}
void store_text() {
Publication list[] = {
{"Sculptor", "Scott McCloud"},
{"The Lighthouse", "Chris Ware"},
{"Human Limitations", "Samuel Johnson"},
{"Onward: A Life of Margaret Atwood", "Rosemary Sullivan"},
{"Above the Earth", "Rohinton Mistry"},
{"School Memories", "He Zhaowu"},
{"Fate", "Cai Chongda"}
};
int total = sizeof(list) / sizeof(list[0]);
FILE *file_ptr = fopen("books.txt", "w");
if (!file_ptr) {
printf("Unable to create text file.\n");
return;
}
for (int idx = 0; idx < total; idx++)
fprintf(file_ptr, "%-38s %-18s\n", list[idx].title, list[idx].writer);
fclose(file_ptr);
}
void load_text() {
Publication collection[CAPACITY];
FILE *file_ptr = fopen("books.txt", "r");
if (!file_ptr) {
printf("Unable to open text file.\n");
return;
}
int pos = 0, items_read;
while (1) {
items_read = fscanf(file_ptr, "%s%s", collection[pos].title, collection[pos].writer);
if (items_read != 2) break;
pos++;
}
for (int idx = 0; idx < pos; idx++)
printf("%d. %-38s%-18s\n", idx + 1, collection[idx].title, collection[idx].writer);
fclose(file_ptr);
}
Omitting the check for successful fscanf may cause an extra iteration when the file ends with whitespace, reading invalid data.
Block-Based Binary File I/O
#include <stdio.h>
#define TITLE_LEN 80
#define AUTHOR_LEN 80
#define CAPACITY 100
typedef struct {
char title[TITLE_LEN];
char writer[AUTHOR_LEN];
} Publication;
void save_binary();
void fetch_binary();
int main() {
save_binary();
fetch_binary();
return 0;
}
void save_binary() {
Publication list[] = {
{"Sculptor", "Scott McCloud"},
{"The Lighthouse", "Chris Ware"},
{"Human Limitations", "Samuel Johnson"},
{"Onward: A Life of Margaret Atwood", "Rosemary Sullivan"},
{"Above the Earth", "Rohinton Mistry"},
{"School Memories", "He Zhaowu"},
{"Fate", "Cai Chongda"}
};
int total = sizeof(list) / sizeof(list[0]);
FILE *file_ptr = fopen("books.dat", "wb");
if (!file_ptr) {
printf("Unable to create binary file.\n");
return;
}
fwrite(list, sizeof(Publication), total, file_ptr);
fclose(file_ptr);
}
void fetch_binary() {
Publication collection[CAPACITY];
FILE *file_ptr = fopen("books.dat", "rb");
if (!file_ptr) {
printf("Unable to open binary file.\n");
return;
}
int pos = 0, items_read;
while (1) {
items_read = fread(&collection[pos], sizeof(Publication), 1, file_ptr);
if (items_read != 1) break;
pos++;
}
for (int idx = 0; idx < pos; idx++)
printf("%d. %-38s%-18s\n", idx + 1, collection[idx].title, collection[idx].writer);
fclose(file_ptr);
}
Without verifying fread results, trailing file markers can produce spurious records.
String and Character Based Text Processing
#include <stdio.h>
#define COUNT 5
#define BUFFER 80
void save_strings();
void load_strings();
void load_chars();
int main() {
save_strings();
load_strings();
load_chars();
return 0;
}
void save_strings() {
const char *lyrics[COUNT] = {
"Working's Blues",
"Everything Will Flow",
"Streets of London",
"Perfect Day",
"Philadelphia"
};
FILE *file_ptr = fopen("songs.txt", "w");
if (!file_ptr) {
printf("Cannot open file for writing.\n");
return;
}
for (int i = 0; i < COUNT; i++) {
fputs(lyrics[i], file_ptr);
fputc('\n', file_ptr);
}
fclose(file_ptr);
}
void load_strings() {
char buffer[COUNT][BUFFER];
FILE *file_ptr = fopen("songs.txt", "r");
if (!file_ptr) {
printf("Cannot open file for string reading.\n");
return;
}
for (int i = 0; i < COUNT; i++)
fgets(buffer[i], BUFFER, file_ptr);
for (int i = 0; i < COUNT; i++)
printf("%d. %s", i + 1, buffer[i]);
fclose(file_ptr);
}
void load_chars() {
FILE *file_ptr = fopen("songs.txt", "r");
if (!file_ptr) {
printf("Cannot open file for char reading.\n");
return;
}
int ch;
while ((ch = fgetc(file_ptr)) != EOF)
putchar(ch);
fclose(file_ptr);
}
Escape sequences like \' represent a single quote; the backslash does not appear literally in output.
Counting Lines and Non-Whitespace Characters
#include <stdio.h>
#include <ctype.h>
int main() {
FILE *file_ptr = fopen("input.txt", "r");
if (!file_ptr) {
perror("Open error");
return 1;
}
int line_count = 0, letter_count = 0;
int cur;
while ((cur = fgetc(file_ptr)) != EOF) {
if (cur == '\n') line_count++;
if (!isspace(cur)) letter_count++;
}
if (letter_count > 0) line_count++;
fclose(file_ptr);
printf("Lines: %d\nNon-whitespace chars: %d\n", line_count, letter_count);
return 0;
}
Processing Structured Records from File
#include <stdio.h>
#include <string.h>
#define SIZE 10
typedef struct {
long roll;
char full_name[20];
float part_a;
float part_b;
float total;
char status[10];
} Candidate;
void input(Candidate arr[], int lim);
void print_all(Candidate arr[], int lim);
void export_pass(Candidate arr[], int lim);
int evaluate(Candidate arr[], int lim, Candidate passed[]);
int main() {
Candidate group[SIZE], cleared[SIZE];
int num_passed;
double rate;
input(group, SIZE);
num_passed = evaluate(group, SIZE, cleared);
printf("\nAll candidates:\n");
print_all(group, SIZE);
export_pass(group, SIZE);
rate = (double)num_passed / SIZE * 100;
printf("Pass rate: %.2f%%\n", rate);
return 0;
}
void print_all(Candidate arr[], int lim) {
printf("RollNo\tName\tPartA\tPartB\tTotal\tStatus\n");
for (int i = 0; i < lim; i++)
printf("%ld\t%s\t%.2f\t%.2f\t%.2f\t%s\n",
arr[i].roll, arr[i].full_name, arr[i].part_a, arr[i].part_b,
arr[i].total, arr[i].status);
}
void input(Candidate arr[], int lim) {
FILE *src = fopen("candidates.txt", "r");
if (!src) {
printf("Failed to open source file.\n");
return;
}
for (int i = 0; i < lim; i++)
fscanf(src, "%ld %s %f %f", &arr[i].roll, arr[i].full_name, &arr[i].part_a, &arr[i].part_b);
fclose(src);
}
void export_pass(Candidate arr[], int lim) {
FILE *dest = fopen("passed_list.txt", "w");
if (!dest) {
printf("Failed to create output file.\n");
return;
}
fprintf(dest, "RollNo\tName\tPartA\tPartB\tTotal\tStatus\n");
for (int i = 0; i < lim; i++) {
if (strcmp(arr[i].status, "Pass") == 0)
fprintf(dest, "%ld\t%s\t%.2f\t%.2f\t%.2f\t%s\n",
arr[i].roll, arr[i].full_name, arr[i].part_a, arr[i].part_b,
arr[i].total, arr[i].status);
}
fclose(dest);
}
int evaluate(Candidate arr[], int lim, Candidate passed[]) {
int count = 0;
for (int i = 0; i < lim; i++) {
arr[i].total = arr[i].part_a + arr[i].part_b;
if (arr[i].total >= 60) {
strcpy(arr[i].status, "Pass");
passed[count++] = arr[i];
} else strcpy(arr[i].status, "Fail");
}
return count;
}
Random Selection of Students and Saving Results
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM_STUDENTS 80
#define PICK_COUNT 5
typedef struct {
int roll;
char full_name[20];
char section[20];
} Pupil;
int main() {
Pupil roster[NUM_STUDENTS];
int chosen[PICK_COUNT];
FILE *src = fopen("roster.txt", "r");
if (!src) {
printf("Cannot access roster file.\n");
return 1;
}
for (int i = 0; i < NUM_STUDENTS; i++)
fscanf(src, "%d %s %s", &roster[i].roll, roster[i].full_name, roster[i].section);
fclose(src);
srand((unsigned)time(NULL));
for (int i = 0; i < PICK_COUNT; i++) {
int idx;
do idx = rand() % NUM_STUDENTS;
while (roster[idx].roll == -1);
chosen[i] = idx;
roster[idx].roll = -1;
}
printf("Selected pupils:\n");
for (int i = 0; i < PICK_COUNT; i++) {
int idx = chosen[i];
printf("Roll: %d, Name: %s, Section: %s\n",
roster[idx].roll, roster[idx].full_name, roster[idx].section);
}
char out_name[50];
printf("Enter output file name: ");
scanf("%s", out_name);
FILE *dest = fopen(out_name, "w");
if (!dest) {
printf("Cannot open destination file.\n");
return 1;
}
fprintf(dest, "Selected pupils:\n");
for (int i = 0; i < PICK_COUNT; i++) {
int idx = chosen[i];
fprintf(dest, "Roll: %d, Name: %s, Section: %s\n",
roster[idx].roll, roster[idx].full_name, roster[idx].section);
}
fclose(dest);
return 0;
}