সি প্রোগ্রামিং ফাইল ইনপুট/আউটপুট(I/O)
ফাইল ইনপুট/আউটপুট(I/O) পরিচালনার জন্য সি প্রোগ্রমিং এ অনেক ধরণের ফাংশন রয়েছে। এই অধ্যায়ে আপনি fprintf(), fscanf(), fread(), fwrite(), fseek এবং আরো অনেক ধরেনের ফাংশন ব্যবহার করে সি এর স্টান্ডার্ড ইনপুট/আউটপুট পরিচালনা করা শিখবেন।
সি প্রোগ্রামিং এ ফাইল হলো আপনার কম্পিউটারের ফিজিক্যাল ডিস্কের মধ্যে একটি স্থান যেখানে তথ্য জমা হয়।
কেন ফাইল প্রয়োজন?
- যখন প্রোগ্রাম এর সমাপ্তি ঘটে তখন সমস্ত তথ্য(Data) হারিয়ে যায়। কিন্তু ফাইলের মধ্যে সংরক্ষণ করলে প্রোগ্রাম শেষ হয়ে গেলেও তথ্য সংরক্ষিত অবস্থায় থাকে।
- আপনাকে যদি অনেক বেশী ডাটা ইনপুট দিতে হয় তাহলে সমস্ত ডাটা ইনপুট দেওয়ার জন্য অনেক সময় লেগে যাবে।
যাইহোক সমস্ত তথ্য(data) সম্বলিত একটি ফাইল যদি আপনার কাছে থাকে তাহলে আপনি সি এর কিছু কমান্ডের সাহায্যে খুব সহজেই সেই কন্টেন্টসমূহ এক্সেস করতে পারেন। - অত্যন্ত সহজভাবে আপনি আপনার ডাটা এক কম্পিউটার থেকে অন্য কম্পিউটারে স্থানান্তর করতে পারেন।
সি ফাইলের ধরণ
আপনি যখন ফাইল নিয়ে ডিল(deal) করবেন তখন দুই ধরণের ফাইল দেখতে পাবেন যা আপনার জানা আবশ্যকঃ
- টেক্সট ফাইল(Text file)
- বাইনারি ফাইল(Binary file)
টেক্সট ফাইল | বাইনারি ফাইল |
---|---|
.txt এক্সটেনশন দিয়ে সাধারণ টেক্সট ফাইল। | .bin এক্সটেনশন দিয়ে আপনার কম্পিউটারে সংরক্ষিত থাকে। |
ডেটা টেক্সট ফরম্যাটে(অ, আ, ক, খ )সংরক্ষণ করে, ফলে সম্পাদনা অনেক সহজ। | ডেটা টেক্সট এর পরিবর্তে বাইনারি ফরম্যাটে(০ এবং ১) সংরক্ষণ করে, ফলে সম্পাদনা কঠিন। |
সহজে পাঠযোগ্য। | পাঠযোগ্য নহে। |
কম পরিশ্রমে রক্ষণাবেক্ষণ করা যায়। | রক্ষণাবেক্ষণ অনেক কঠিন। |
মেমোরিতে অনেক স্পেস দখল করে। | কম স্পেসে অনেক তথ্য ধারণ করতে পারে। |
নিম্নমানের সিকিউরিটি সরবরাহ করে। | সর্বোচ্চ মানের সিকিউরিটি সরবরাহ করে। |
সি ফাইল অপারেশন
সি প্রোগ্রামে টেক্সট অথবা বাইনারি ফাইল অপারেশনের জন্য চারটি মুখ্য অপারেশন রয়েছেঃ
- নতুন ফাইল তৈরি করা।
- বিদ্যমান ফাইল খুলা।
- ফাইল বন্ধ করা।
- বিদ্যমান ফাইল থেকে তথ্য পাঠ এবং তথ্য যোগ করা।
সি ফাইল নিয়ে কাজ করা
আপনি যখন ফাইল নিয়ে কাজ করবেন তখন file
টাইপের একটি পয়েন্টার ডিক্লেয়ার করতে হবে। প্রোগ্রাম এবং ফাইলের মধ্যে যোগাযোগ সৃষ্টির জন্য এই ডিক্লেয়ারেশনের প্রয়োজন।
FILE *fptr;
সি ফাইল তৈরি এবং সম্পাদনা
"stdio.h" হেডার ফাইলের আওতাধীন fopen() লাইব্রেরী ফাংশন এর মাধ্যমে ফাইল খুলার কাজটি করা হয়।
সি ফাইল খুলার সিনট্যাক্স
ptr = fopen("fileopen","mode")
উদাহরণস্বরূপঃ
fopen("E:\\cprogramming\\newFile.txt","w");
fopen("E:\\cprogramming\\oldFile.bin","rb");
- ধরুন
E:\cprogramming
লোকেশনে প্রথম টেক্সট ফাইলnewFile.txt
ফাইলটি পূর্বে থেকে বিদ্যমান নাই। ফাইল মোড(mode) "w" অনুসারে প্রথম ফাংশনটিnewFile.txt
নামের একটি নতুন ফাইল তৈরি করে।
ফাইলের <W> মোড আপনাকে নতুন ফাইল তৈরি এবং সম্পাদনা/ওভার রাইট করার সম্মতি দেয়। - আবার ধরুন E:\cprogramming লোকেশনে দ্বিতীয় বাইনারি ফাইল
oldFile.bin
ফাইলটি পূর্বে থেকেই বিদ্যমান আছে। দ্বিতীয় ফাংশনটি বিদ্যমান ফাইলকে বাইনারি মোডে( 'rb') পাঠ করার জন্য ওপেন করে।
'r' মোডে কোনো ফাইল ওপেন করলে আপনি শুধু ফাইলটি পাঠ(read) করার অনুমতি পাবেন, কোনো কিছু পরিবর্তন/লেখা-লেখি করতে পারবেন না।
ফাইল মোড | বর্ণনা | ফাইল বিদ্যমান না থাকলে |
---|---|---|
r | পাঠ করার জন্য ফাইল ওপেন করে। | ফাইল বিদ্যমান না থাকলে fopen() ফাংশন NULL রিটার্ন করে। |
rb | বাইনারি মোডে পাঠ করার জন্য ফাইল ওপেন করে। | ফাইল বিদ্যমান না থাকলে fopen() ফাংশন NULL রিটার্ন করে। |
w | লেখার জন্য ফাইল ওপেন করে। | ফাইল বিদ্যমান থাকলে এর কন্টেন্ট-সমূহ অভার-রাইট হয়ে যাবে। যদি ফাইল বিদ্যমান না থাকে তাহলে নতুন ফাইল তৈরি হবে। |
wb | বাইনারি মোডে লেখার জন্য ফাইল ওপেন করে। | ফাইল বিদ্যমান থাকলে এর কন্টেন্ট-সমূহ অভার-রাইট হয়ে যাবে। যদি ফাইল বিদ্যমান না থাকে তাহলে নতুন ফাইল তৈরি হবে। |
a | ডেটা সংযোজন(append) করার জন্য ফাইল ওপেন করে। সুতরাং ফাইলের শেষে তথ্য যোগ করা যায়। | যদি ফাইল বিদ্যমান না থাকে তাহলে নতুন ফাইল তৈরি হবে। |
ab | বাইনারি মোডে ডেটা সংযোজন(append) করার জন্য ফাইল ওপেন করে। সুতরাং ফাইলের শেষে তথ্য যোগ করা যায়। | যদি ফাইল বিদ্যমান না থাকে তাহলে নতুন ফাইল তৈরি হবে। |
r+ | পাঠ এবং লেখা উভয়ের জন্য ফাইল ওপেন করে। | ফাইল বিদ্যমান না থাকলে fopen() ফাংশন NULL রিটার্ন করে। |
rb+ | বাইনারি মোডে পাঠ এবং লেখা উভয়ের জন্য ফাইল ওপেন করে। | ফাইল বিদ্যমান না থাকলে fopen() ফাংশন NULL রিটার্ন করে। |
w+ | পাঠ এবং লেখা উভয়ের জন্য ওপেন করে। | ফাইল বিদ্যমান থাকলে এর কন্টেন্ট-সমূহ অভার-রাইট হয়ে যাবে। যদি ফাইল বিদ্যমান না থাকে তাহলে নতুন ফাইল তৈরি হবে। |
wb+ | বাইনারি মোডে পাঠ এবং লেখা উভয়ের জন্য ফাইল ওপেন করে। | ফাইল বিদ্যমান থাকলে এর কন্টেন্ট-সমূহ অভার-রাইট হয়ে যাবে। যদি বিদ্যমান না থাকে তাহলে নতুন ফাইল তৈরি হবে। |
a+ | ডেটা পাঠ এবং সংযোজন(append) উভয়ের জন্য ফাইল ওপেন করে। | যদি ফাইল বিদ্যমান না থাকে তাহলে নতুন ফাইল তৈরি হবে। |
ab+ | বাইনারি মোডে ডেটা পাঠ এবং সংযোজন(append) উভয়ের জন্য ফাইল ওপেন করে। | যদি ফাইল বিদ্যমান না থাকে তাহলে নতুন ফাইল তৈরি হবে। |
সি ফাইল বন্ধ করা
পড়া/লেখার পরে টেক্সট এবং বাইনারি উভয় ফাইলকেই বন্ধ করা উচিৎ।
fclose() লাইব্রেরী ফাংশন ব্যবহার করে ফাইল বন্ধের কাজটি করা হয়।
সি ফাইল বন্ধ করার সিনট্যাক্স
fclose(fptr); //এখানে fptr হলো যে ফাইলকে বন্ধ করবো সেই ফাইলের ফাইল পয়েন্টার
সি টেক্সট ফাইল পড়া এবং লেখা
টেক্সট ফাইলে পড়া এবং লেখার জন্য আমরা যথাক্রমে fprintf()
এবং fscanf()
লাইব্রেরী ফাংশন ব্যবহার করি।
fprintf()
এবং fscanf()
ফাংশনটি দুটি printf()
এবং scanf()
এর ফাইল ভার্সন।
শুধুমাত্র পার্থক্য হলো fprint এবং fscanf ফাংশন দুটি ফাইল এর অন্তত একটি পয়েন্টার আশা করে।
সি Text ফাইলে লেখা
উদাহরনঃ fprintf() ফাংশন ব্যবহার করে ফাইলে লেখা
#include <stdio.h>
int main()
{
int num;
FILE *fptr;
fptr = fopen("C:\\program.txt","w");
if(fptr == NULL)
{
printf("Error!");
exit(1);
}
printf("Enter num: ");
scanf("%d",&num);
fprintf(fptr,"%d",num);
fclose(fptr);
return 0;
}
এই প্রোগ্রামটি ইউজার থেকে নম্বর গ্রহণ করে program.txt
ফাইলে জমা করে।
এই প্রোগ্রামটি কম্পাইল এবং রান করানোর পরে আপনার কম্পিউটারের সি ড্রাইভে program.txt নামের একটি ফাইল দেখতে পাবেন। আপনি যখন ফাইলটি ওপেন করবেন তখন আপনার প্রবেশ করানো পূর্ণসংখ্যাটি(integer number) দেখতে পাবেন।
সি Text ফাইল থেকে পড়া
উদাহরনঃ fscanf() লাইব্রেরী ফাংশন ব্যবহার করে ফাইল পড়া।
#include <stdio.h>
int main()
{
int num;
FILE *fptr;
if ((fptr = fopen("C:\\program.txt","r")) == NULL){
printf("Error! opening file");
// ফাইল পয়েন্টার NULL রিটার্ন করলে প্রোগ্রাম থেকে বের হয়ে যাবে।
exit(1);
}
fscanf(fptr,"%d",&num);
printf("Value of n=%d",num);
fclose(fptr);
return 0;
}
এই প্রোগ্রামটি program.txt
ফাইলে বিদ্যমান পূর্ণসংখ্যা পড়ে এবং স্ক্রিনে প্রিন্ট করে।
প্রথম উদাহরণে যদি সফলভাবে ফাইল তৈরি হয় তাহলে এই প্রোগ্রাম রান করিয়ে আপনি প্রবেশ করানো পূর্ণসংখ্যাটি পাবেন।
অন্যান্য ফাংশন যেমন- fgetchar()
, fputc()
ইত্যাদি একইভাবে ব্যবহার করতে পারেন।
সি বাইনারি ফাইলে পড়া এবং লেখা
আপনার কম্পিউটার ডিস্কে বাইনারি ফাইল লেখা এবং সেখান থেকে বাইনারি ফাইল পড়ার জন্য যথাক্রমে fwrite()
এবং fread()
লাইব্রেরী ফাংশন ব্যবহার করা হয়।
সি বাইনারি ফাইলে কাজ করা
বাইনারি ফাইলে কোনো কিছু লেখার জন্য আপনাকে fwrite() ফাংশনটি ব্যবহার করতে হবে। এই ফাংশনটি চারটি আরগুমেন্ট গ্রহণ করে। যথাঃ তথ্য(data) লিপিবদ্ধ করার জন্য কম্পিউটার ডিস্কের ঠিকানা, ডিস্কে লিপিবদ্ধ তথ্যের পরিমাণ(Size), তথ্যের সংখ্যা এবং তথ্য জমা হবে এমন স্থানের ফাইলের পয়েন্টার।
সি বাইনারি ফাইল লেখার সিনট্যাক্স
fwrite(data_address, data_size, data_numbers, pointer_to_file);
উদাহরনঃ fwrite() ব্যবহার করে বাইনারি ফাইল লেখা।
#include <stdio.h>
struct threeNum
{
int n1, n2, n3;
};
int main()
{
int n;
struct threeNum num;
FILE *fptr;
if ((fptr = fopen("C:\\program.bin","wb")) == NULL){
printf("Error! opening file");
// Program exits if the file pointer returns NULL.
exit(1);
}
for(n = 1; n < 5; ++n)
{
num.n1 = n;
num.n2 = 5n;
num.n3 = 5n + 1;
fwrite(&num, sizeof(struct threeNum), 1, *fptr);
}
fclose(fptr);
return 0;
}
এই প্রোগ্রামের মাধ্যমে আপনি সি ড্রাইভে program.bin
নামের একটি নতুন ফাইল তৈরি করতে পারেন।
আমরা তিনটি নম্বর - n1, n2 এবং n3 সহ একটি স্ট্রাকচার ভ্যারিয়েবল threeNum
ডিক্লেয়ার করেছি এবং main ফাংশনে ইহাকে num হিসাবে ডিফাইন করেছি।
এখন for লুপের ভিতরে fwrite() ফাংশন ব্যবহার করে ফাইলে ভ্যালু জমা(store) করতে পারি।
প্রথম প্যারামিটারটি num ভ্যারিয়েবলের এড্রেস গ্রহণ করে এবং দ্বিতীয় প্যারামিটারটি threeNum
স্ট্রাকচারের সাইজ গ্রহণ করে।
যেহেতু আমরা num এর একটিমাত্র instance ইনসার্ট করেছি, সুতরাং তৃতীয় প্যারমিটারের ভ্যালু 1
। শেষ প্যারামিটার *fptr
ডেটা স্টোরের ফাইলকে নির্দেশ করে।
সবশেষে আমরা ফাইলকে বন্ধ করি।
বাইনারি ফাইল থেকে পড়া
উপরের fwrite()
ফাংশনের ন্যায় fread()
ফাংশনও চারটি আর্গুমেন্ট গ্রহণ করে।
বাইনারি ফাইল পড়ার সিনট্যাক্স
fread(data_address, data_size, data_numbers, pointer_to_file);
উদাহরনঃ fread() ফাংশন ব্যবহার করে বাইনারি ফাইল থেকে তথ্য পড়াঃ
#include <stdio.h>
struct threeNum
{
int n1, n2, n3;
};
int main()
{
int n;
struct threeNum num;
FILE *fptr;
if ((fptr = fopen("C:\\program.bin","rb")) == NULL){
printf("Error! opening file");
// ফাইল পয়েন্টার NULL রিটার্ন করলে প্রোগ্রাম থেকে বের হয়ে যাবে।
exit(1);
}
for(n = 1; n < 5; ++n)
{
fread(&num, sizeof(struct threeNum), 1, *fptr);
printf("n1: %d\tn2: %d\tn3: %d", num.n1, num.n2, num.n3);
}
fclose(fptr);
return 0;
}
এই প্রোগ্রামটির মাধ্যমে আপনি একই ফাইল program.bin
কে পড়তে পারবেন এবং ফাইলের রেকর্ড-সমূহকে একের পরে এক আবৃতি(loop) করতে পারবেন।
সহজ অর্থে, আপনি *fptr ফাইল পয়েন্টার দ্বারা num স্ট্রাকচারে নির্দেশিতে threeNum
সাইজের একটি threeNum
রেকর্ডকে পড়তে পারবেন।
উপরের উদাহরণে আপনি যা কিছু রেকর্ড করবেন ঐ একই রেকর্ড ফিরে পাবেন।
সি fseek() এর মাধ্যমে তথ্য প্রাপ্তি
ফাইলের মধ্যে যদি বহু তথ্য রেকর্ড করা থাকে এবং একটি নির্দিষ্ট পজিশনে ঐ রেকর্ডকে এক্সেস করার প্রয়োজন হয় তাহলে সমগ্র রেকর্ড লুপ(loop) করার প্রয়োজন হবে।
ইহা প্রচুর পরিমাণ মেমোরি এবং অপারেশনের সময় অপচয় করবে। এই সমস্যা থেকে কাটিয়ে উঠার জন্য আপনি fseek() ফাংশন ব্যবহার করতে পারেন যার মাধ্যমে সময় ও শ্রম উভয়ই সাশ্রয় হবে।
fseek() ফাংশন ফাইলের মধ্য থেকে চাওয়া রেকর্ডে অতি সহজেই কার্সর নিয়ে যায়।
fseek() এর সিনট্যাক্স
fseek(FILE * stream, long int offset, int whence)
এখানে ফাংশনের প্রথম প্যারামিটার stream হলো ফাইলের পয়েন্টার, দ্বিতীয় প্যারামিটারটি রেকর্ডের পজিশন যাকে খুঁজে বের করতে হবে, এবং তৃতীয় প্যারামিটারটি হলো লোকেশন যেখান থেকে offset শুরু করবে।
Whence | বর্ণনা |
---|---|
SEKK_SET | ফাইলের একেবারে শুরু থেকে মুদ্রণ(offset) শুরু হয়। |
SEKK_END | ফাইলের একেবারে শেষ থেকে মুদ্রণ(offset) শুরু হয়। |
SEKK_CUR | ফাইল কার্সরের চলমান লোকেশন থেকে মুদ্রণ শুরু হয়। |
উদাহরনঃ fseek() ফাংশনের প্রয়োগ
#include <stdio.h>
struct threeNum
{
int n1, n2, n3;
};
int main()
{
int n;
struct threeNum num;
FILE *fptr;
if ((fptr = fopen("C:\\program.bin","rb")) == NULL){
printf("Error! opening file");
// ফাইল পয়েন্টার NULL রিটার্ন করলে প্রোগ্রাম এখান থেকে বের হয়ে যায়।
exit(1);
}
// কার্সর একবারে ফাইলের শেষে যায়।
fseek(fptr, sizeof(struct threeNum), SEEK_END);
for(n = 1; n < 5; ++n)
{
fread(&num, sizeof(struct threeNum), 1, *fptr);
printf("n1: %d\tn2: %d\tn3: %d", num.n1, num.n2, num.n3);
}
fclose(fptr);
return 0;
}
এই প্রোগ্রামটি উল্টা দিক হতে(অর্থাৎ শেষ থেকে প্রথমে)program.bin
বাইনারি ফাইল থেকে রেকর্ড পড়া শুরু করে এবং সঙ্গে সঙ্গে প্রিন্টও করে।