File I/O — Text, Binary, Random Access
ফাইলসিস্টেমের সাথে কথোপকথন
1. Files as Streams
C-তে প্রতিটি ফাইল একটি FILE * stream-এর মাধ্যমে access করা হয়। fopen দিয়ে খুলে, fclose দিয়ে বন্ধ করতে হয়।
FILE *f = fopen("data.txt", "r");
if (!f) { perror("fopen"); return 1; }
// ... use f ...
fclose(f);
fopen ব্যর্থ হলে NULL ফেরত দেয়। Cause জানতে perror বা strerror(errno) ব্যবহার করুন।2. Open Modes
| Mode | Meaning |
|---|---|
"r" | Read — file অবশ্যই থাকতে হবে |
"w" | Write — না থাকলে তৈরি হয়, থাকলে truncate |
"a" | Append — শেষে লেখা, না থাকলে তৈরি |
"r+" | Read + write (file থাকতে হবে) |
"w+" | Write + read (truncate) |
"rb", "wb", … | Binary mode (Windows-এ গুরুত্বপূর্ণ) |
3. Reading Line by Line
Online runner-এ সাধারণত ফাইল তৈরি করা যায় না, তাই এই demo stdin থেকে পড়ছে — কিন্তু pattern হুবহু একই, শুধু stdin-এর জায়গায় FILE * বসালেই হয়।
#include <stdio.h>
int main(void) {
FILE *f = stdin; // in real code: fopen("data.txt", "r")
char line[1024];
int n = 0;
while (fgets(line, sizeof line, f)) {
printf("%3d | %s", ++n, line);
}
printf("(total %d lines)\n", n);
return 0;
}
4. Writing and Reading — End-to-End Demo
নিচের প্রোগ্রামটি একটি temporary file-এ লিখে, বন্ধ করে, আবার খুলে পড়ে — পুরো cycle এক জায়গায়।
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char *path = "notes.txt";
// 1) write
FILE *w = fopen(path, "w");
if (!w) { perror("open for write"); return 1; }
fprintf(w, "Hello, Bangladesh!\n");
fprintf(w, "Line 2, with a number %d\n", 42);
fclose(w);
// 2) read back
FILE *r = fopen(path, "r");
if (!r) { perror("open for read"); return 1; }
char line[256];
while (fgets(line, sizeof line, r)) fputs(line, stdout);
fclose(r);
remove(path); // clean up the temp file
return 0;
}
5. Binary I/O — fread / fwrite
typedef struct { char name[32]; int id; double gpa; } Student;
Student arr[100];
fwrite(arr, sizeof arr[0], n, f); // write n records
fread(arr, sizeof arr[0], n, f); // read them back
6. Random Access — fseek & ftell
fseek(f, 0, SEEK_END); // go to the end
long size = ftell(f); // file size in bytes
rewind(f); // back to the start
fseek(f, 100, SEEK_SET); // absolute offset 100
fseek(f, -10, SEEK_CUR); // 10 bytes backwards
7. Error Handling
#include <errno.h>
FILE *f = fopen("nope.txt", "r");
if (!f) {
fprintf(stderr, "open failed: %s\n", strerror(errno));
perror("context"); // prints "context: No such file or directory"
return 1;
}
প্রতিটি I/O function-এর return value যাচাই করুন। fgets NULL দিলে হয় EOF, না হয় read error — ferror(f) আর feof(f) দিয়ে পার্থক্য করা যায়।
8. Practice Problems
- Copy one file to another byte-by-byte.একটি file অপরটিতে byte-by-byte কপি করুন।
✨ Show Answer
fcopy.c#include <stdio.h> int main(void) { const char *src = "a.txt", *dst = "b.txt"; FILE *in = fopen(src, "wb"); fputs("ABCL TECH", in); fclose(in); in = fopen(src, "rb"); FILE *out = fopen(dst, "wb"); int c; while ((c = fgetc(in)) != EOF) fputc(c, out); fclose(in); fclose(out); // print result out = fopen(dst, "r"); char buf[64] = {0}; fread(buf, 1, 63, out); puts(buf); fclose(out); remove(src); remove(dst); return 0; } - Count lines in a file.একটি file-এ লাইন সংখ্যা গুনুন।
✨ Show Answer
count_lines.c#include <stdio.h> int main(void) { const char *p = "sample.txt"; FILE *w = fopen(p, "w"); fputs("first\nsecond\nthird\n", w); fclose(w); FILE *r = fopen(p, "r"); int n = 0, c; while ((c = fgetc(r)) != EOF) if (c == '\n') n++; fclose(r); printf("lines = %d\n", n); remove(p); return 0; } - Count occurrences of a word in a file.একটি file-এ একটি নির্দিষ্ট শব্দ কতবার আছে গুনুন।
✨ Show Answer
count_word.c#include <stdio.h> #include <string.h> int main(void) { const char *p = "essay.txt", *needle = "C"; FILE *w = fopen(p, "w"); fputs("I love C. C is fun. Systems need C.\n", w); fclose(w); FILE *f = fopen(p, "r"); char line[512]; int total = 0; while (fgets(line, sizeof line, f)) { char *q = line; while ((q = strstr(q, needle))) { total++; q += strlen(needle); } } fclose(f); printf(""%s" appears %d times\n", needle, total); remove(p); return 0; } - Append a log entry to a file on each run.প্রতিবার প্রোগ্রাম চালালে একটি log entry file-এ append হবে।
✨ Show Answer
append_log.c#include <stdio.h> #include <time.h> int main(void) { const char *p = "app.log"; FILE *f = fopen(p, "a"); // append fprintf(f, "run at time %ld\n", (long)time(NULL)); fclose(f); // show contents f = fopen(p, "r"); char line[256]; while (fgets(line, sizeof line, f)) fputs(line, stdout); fclose(f); remove(p); return 0; } - Read integers from a file into an array, then print sorted.File থেকে integer পড়ে array-তে রাখুন, তারপর sort করে প্রিন্ট করুন।
✨ Show Answer
sort_file.c#include <stdio.h> #include <stdlib.h> int cmp(const void *a, const void *b) { return *(const int*)a - *(const int*)b; } int main(void) { const char *p = "nums.txt"; FILE *w = fopen(p, "w"); fputs("42 7 19 3 88 21 56 11", w); fclose(w); FILE *r = fopen(p, "r"); int a[100], n = 0; while (n < 100 && fscanf(r, "%d", &a[n]) == 1) n++; fclose(r); qsort(a, n, sizeof *a, cmp); for (int i = 0; i < n; i++) printf("%d ", a[i]); putchar('\n'); remove(p); return 0; } - Save an array of Students to a binary file and read it back.Student array-কে binary file-এ save করে আবার পড়ুন।
✨ Show Answer
students_bin.c#include <stdio.h> #include <string.h> typedef struct { char name[32]; int id; double gpa; } Student; int main(void) { const char *p = "students.dat"; Student a[3] = { {"Arif",101,3.72}, {"Nusrat",102,3.92}, {"Zahid",103,3.55} }; FILE *w = fopen(p, "wb"); fwrite(a, sizeof a[0], 3, w); fclose(w); Student b[3] = {0}; FILE *r = fopen(p, "rb"); fread(b, sizeof b[0], 3, r); fclose(r); for (int i = 0; i < 3; i++) printf("%s id=%d gpa=%.2f\n", b[i].name, b[i].id, b[i].gpa); remove(p); return 0; } - Implement
tail -n— print the last N lines of a file.tail -n-এর মতো file-এর শেষ N লাইন প্রিন্ট করুন।✨ Show Answer
tail_n.c#include <stdio.h> #include <string.h> int main(void) { const char *p = "sample.txt"; FILE *w = fopen(p, "w"); for (int i = 1; i <= 10; i++) fprintf(w, "line %d\n", i); fclose(w); const int N = 3; char buf[N][256] = {{0}}; FILE *r = fopen(p, "r"); int count = 0; char line[256]; while (fgets(line, sizeof line, r)) { strncpy(buf[count % N], line, 255); count++; } fclose(r); int start = count >= N ? count % N : 0; int shown = count < N ? count : N; for (int i = 0; i < shown; i++) fputs(buf[(start + i) % N], stdout); remove(p); return 0; } - Compute the size of a file without reading its contents.Content না পড়েই একটি file-এর size বের করুন।
✨ Show Answer
filesize.c#include <stdio.h> int main(void) { const char *p = "big.bin"; FILE *w = fopen(p, "wb"); char pad[100] = {0}; fwrite(pad, 1, 100, w); fclose(w); FILE *f = fopen(p, "rb"); fseek(f, 0, SEEK_END); printf("size = %ld bytes\n", ftell(f)); fclose(f); remove(p); return 0; } - Find and replace all occurrences of one word in a text file.একটি text file-এর সব জায়গায় একটি word-কে অন্যটি দিয়ে replace করুন।
✨ Show Answer
সহজ approach: পুরো ফাইল memory-তে পড়ুন, একটি নতুন buffer-এ
find/replaceকরে write করুন। Large file হলে line-by-line process করুন।replace.c#include <stdio.h> #include <string.h> void process_line(const char *src, const char *find, const char *repl, FILE *out) { size_t fl = strlen(find); const char *p = src, *q; while ((q = strstr(p, find))) { fwrite(p, 1, q - p, out); fputs(repl, out); p = q + fl; } fputs(p, out); } int main(void) { const char *in_p = "in.txt", *out_p = "out.txt"; FILE *w = fopen(in_p, "w"); fputs("C is fun. C makes systems go.\n", w); fclose(w); FILE *r = fopen(in_p, "r"); FILE *o = fopen(out_p, "w"); char line[1024]; while (fgets(line, sizeof line, r)) process_line(line, "C", "ABCL TECH", o); fclose(r); fclose(o); FILE *s = fopen(out_p, "r"); while (fgets(line, sizeof line, s)) fputs(line, stdout); fclose(s); remove(in_p); remove(out_p); return 0; } - Concatenate multiple files (Unix
cat).একাধিক file concatenate করুন (cat-এর মতো)।✨ Show Answer
cat_many.c#include <stdio.h> void cat_one(const char *p) { FILE *f = fopen(p, "r"); if (!f) { perror(p); return; } int c; while ((c = fgetc(f)) != EOF) fputc(c, stdout); fclose(f); } int main(void) { // seed two sample files FILE *w = fopen("a.txt", "w"); fputs("first\n", w); fclose(w); w = fopen("b.txt", "w"); fputs("second\n", w); fclose(w); const char *files[] = { "a.txt", "b.txt" }; for (int i = 0; i < 2; i++) cat_one(files[i]); remove("a.txt"); remove("b.txt"); return 0; } - Build a tiny fixed-size-record database using
fseek.fseekদিয়ে ছোট fixed-record DB বানান।✨ Show Answer
tiny_db.c#include <stdio.h> #include <string.h> typedef struct { int id; char name[32]; } Rec; int main(void) { const char *db = "mini.db"; FILE *f = fopen(db, "wb+"); Rec a = { 1, "Alice" }, b = { 2, "Bob" }; fwrite(&a, sizeof a, 1, f); fwrite(&b, sizeof b, 1, f); // seek to record #1 (0-indexed) and read it fseek(f, 1 * sizeof(Rec), SEEK_SET); Rec r; fread(&r, sizeof r, 1, f); printf("rec[1] = id=%d name=%s\n", r.id, r.name); fclose(f); remove(db); return 0; } - Why do you need
"rb"on Windows but not on Linux?Windows-এ"rb"কেন দরকার, Linux-এ কেন নয়?✨ Show Answer
Windows-এর text mode read/write করার সময়
\r\n-কে\n-এ রূপান্তর করে দেয় (এবং লেখার সময় উল্টোটা)। Binary ডেটার জন্য এটি বিপর্যয়কর — একটি 0x0D byte হারিয়ে যেতে পারে।"rb"/"wb"দিলে সেই auto-translation বন্ধ থাকে। Linux/macOS-এ text ও binary একই — তাই পার্থক্য নেই। তবু portable কোডে সবসময়"rb"/"wb"লিখুন।
Glossary (শব্দকোষ)
| Term | Meaning | বাংলায় |
|---|---|---|
FILE * | Opaque pointer representing an open file/stream. | খোলা file/stream-এর pointer। |
fopen | Opens a file and returns a FILE *. | File খুলে FILE * ফেরত দেয়। |
fclose | Flushes buffers and closes the file. | Buffer flush করে file বন্ধ করে। |
| Mode String | "r", "w", "a", "rb", "wb" — open semantics. | File খোলার পদ্ধতি বর্ণনাকারী string। |
| Text Mode | Newlines may be translated by the platform. | Platform অনুযায়ী newline রূপান্তর হয়। |
| Binary Mode | Reads/writes bytes verbatim. | Byte যেমন আছে তেমনই read/write হয়। |
fread / fwrite | Block read/write of binary records. | Binary record read/write করা। |
fprintf / fscanf | Formatted I/O on a file stream. | File stream-এ formatted I/O। |
fgets | Reads a line of text up to a size limit. | Size সীমাসহ এক লাইন পড়া। |
fseek / ftell | Move/get the file position for random access. | Random access-এর জন্য position সরানো/পড়া। |
rewind | Resets file position to the beginning. | Position শুরুতে ফিরিয়ে আনা। |
| EOF | End-of-file indicator returned by read functions. | "ফাইল শেষ" নির্দেশক। |
ferror / perror | Inspect / print stream errors. | Stream error যাচাই/print করা। |
Summary — Module 20
Open, check, read/write, close। fgets text line-এর জন্য, fread/fwrite binary record-এর জন্য, fseek random access-এর জন্য। প্রতিটি কাজের error check করুন — perror বা ferror।