ইনপুট-আউটপুট ও লাইব্রেরি ফাংশন
সি প্রোগ্রামিং: printf ও scanf এর বিস্তারিত ব্যবহার, আউটপুট ফরম্যাটিং, এস্কেপ সিকোয়েন্স এবং math.h লাইব্রেরি ফাংশন।
ইনপুট-আউটপুট ও লাইব্রেরি ফাংশন
- সি প্রোগ্রামিং: ইনপুট-আউটপুট ও লাইব্রেরি ফাংশন
- স্মার্ট প্রোগ্রাম বনাম বোবা ক্যালকুলেটর
- আউটপুট ফাংশন: printf()
- ফরম্যাট স্পেসিফায়ার (Format Specifier)
- এস্কেপ সিকোয়েন্স (Escape Sequence)
- আউটপুট ফরম্যাটিং (Formatting)
- ইনপুট ফাংশন: scanf()
- অ্যাম্পারস্যান্ড (&) এর রহস্য
- ইন্টারেক্টিভ প্রোগ্রাম তৈরি (Prompting)
- লাইব্রেরি ফাংশন কী?
- গাণিতিক ফাংশন: math.h
- ত্রিকোণমিতিক ফাংশন ও সতর্কতা
- অক্ষর ও স্ট্রিং ইনপুট-আউটপুট
- প্র্যাকটিক্যাল: ত্রিভুজের ক্ষেত্রফল নির্ণয়
- সতর্কতা: যেসব ভুল সচরাচর হয়
- সারসংক্ষেপ
ইনপুট-আউটপুট ও লাইব্রেরি ফাংশন
লেকচার ১০-এর ধারাবাহিকতায় আজ আমরা সি প্রোগ্রামিংয়ের অত্যন্ত গুরুত্বপূর্ণ অংশ—ইনপুট-আউটপুট স্টেটমেন্ট এবং লাইব্রেরি ফাংশন নিয়ে বিস্তারিত আলোচনা করব।
একটি ক্যালকুলেটর এবং একটি স্মার্ট সফটওয়্যারের মধ্যে মূল পার্থক্য কী? ক্যালকুলেটরে আপনি যা টাইপ করেন, সে শুধু তাই গণনা করে। কিন্তু একটি স্মার্ট প্রোগ্রাম ব্যবহারকারীর কাছ থেকে ডেটা নেয় (Input), সেই ডেটা প্রসেস করে এবং অর্থবহ ফলাফল প্রদর্শন করে (Output)। এই Input-Process-Output (IPO) সাইকেলই হলো যেকোনো সফটওয়্যারের প্রাণ। সি ল্যাঙ্গুয়েজে এই কাজগুলো করার জন্য printf() এবং scanf() এর মতো ফাংশনগুলো কীভাবে মেমোরি লেভেলে কাজ করে, তা আমরা আজ গভীরে গিয়ে শিখব।
১. আউটপুট ফাংশন: printf()
printf() হলো সি ল্যাঙ্গুয়েজের প্রধান আউটপুট ফাংশন যা stdio.h (Standard Input Output) হেডার ফাইলের অধীনে থাকে। এটি মনিটরের স্ক্রিনে টেক্সট বা ভেরিয়েবলের মান প্রদর্শন করে।
গঠন (Syntax):
printf("Control String", Argument List);
এখানে Control String ডাবল কোটেশনের মধ্যে থাকে এবং এতে সাধারণ টেক্সট বা ফরম্যাট স্পেসিফায়ার থাকতে পারে। Argument List-এ কমা দিয়ে ভেরিয়েবলগুলোর নাম লেখা হয়।
ফরম্যাট স্পেসিফায়ার (Format Specifier)
ফরম্যাট স্পেসিফায়ার কম্পাইলারকে বলে দেয় মেমোরি থেকে ডেটাটি কী ফরম্যাটে স্ক্রিনে দেখাতে হবে। এটি সবসময় % চিহ্ন দিয়ে শুরু হয়।
সংজ্ঞা (Definition): ফরম্যাট স্পেসিফায়ার (Format Specifier) হলো % চিহ্নযুক্ত বিশেষ ক্যারেক্টার যা ইনপুট বা আউটপুট ফাংশনে ভেরিয়েবলের ডেটা টাইপ নির্দেশ করে এবং কম্পাইলারকে জানায় কীভাবে ডেটা প্রসেস বা প্রদর্শন করতে হবে।
নিচে বহুল ব্যবহৃত ফরম্যাট স্পেসিফায়ারের তালিকা দেওয়া হলো যা পরীক্ষার জন্য অত্যন্ত গুরুত্বপূর্ণ:
| ফরম্যাট স্পেসিফায়ার | ডেটা টাইপ | বর্ণনা |
|---|---|---|
%d বা %i |
int |
পূর্ণসংখ্যা (Integer) প্রিন্ট করতে |
%f |
float |
দশমিক সংখ্যা (Floating point) প্রিন্ট করতে |
%lf |
double |
বড় দশমিক সংখ্যা (Double precision) প্রিন্ট করতে |
%c |
char |
একটি মাত্র অক্ষর (Character) প্রিন্ট করতে |
%s |
char[] |
শব্দ বা বাক্য (String) প্রিন্ট করতে |
%o |
int |
অক্টাল (Octal) সংখ্যা প্রিন্ট করতে |
%x বা %X |
int |
হেক্সাডেসিমেল (Hexadecimal) সংখ্যা প্রিন্ট করতে |
পরীক্ষার টিপস (Exam Tip): প্রায়ই MCQ-তে প্রশ্ন আসে double ডেটা টাইপের জন্য কোন স্পেসিফায়ার ব্যবহৃত হয়। সঠিক উত্তর %lf (long float)। তবে float এর জন্য শুধুই %f।
আউটপুট ফিল্ড ফরম্যাটিং (Output Field Formatting)
শুধু মান প্রিন্ট করাই যথেষ্ট নয়, অনেক সময় আউটপুটকে সুন্দরভাবে সাজাতে হয়। একে বলা হয় ফিল্ড ফরম্যাটিং। এর মাধ্যমে আমরা বলে দিতে পারি একটি সংখ্যা প্রিন্ট করতে স্ক্রিনে কয়টি ঘর (space) বরাদ্দ হবে।
গুরুত্বপূর্ণ ফরম্যাটিং নিয়ম:
%wd(যেমন%5d): এখানেwহলো মোট জায়গা বা Width। যদি সংখ্যাটি ছোট হয়, তবে বামপাশে খালি জায়গা বা স্পেস রেখে ডানদিক (Right Align) থেকে প্রিন্ট হবে।%-wd(যেমন%-5d): মাইনাস চিহ্ন থাকলে সংখ্যাটি বামদিক (Left Align) থেকে প্রিন্ট হবে এবং ডানপাশে খালি জায়গা থাকবে।%.pf(যেমন%.2f): দশমিকের পর কত ঘর পর্যন্ত দেখাবে তা নির্ধারণ করে।%.2fমানে দশমিকের পর ২ ঘর।
উদাহরণ (Example):
ধরি, int a = 50; এবং float b = 3.14159;
printf("%5d", a);→_ _ _ 5 0(মোট ৫ ঘর, বামে ৩টি স্পেস)printf("%-5d", a);→5 0 _ _ _(মোট ৫ ঘর, ডানে ৩টি স্পেস)printf("%.2f", b);→3.14(দশমিকের পর ২ ঘর)printf("%.0f", b);→3(দশমিক অংশ বাদ দিয়ে রাউন্ড ফিগার)
২. এস্কেপ সিকোয়েন্স (Escape Sequence)
প্রোগ্রামের আউটপুট সাজানোর জন্য ব্যাকস্ল্যাশ (\) দিয়ে শুরু হওয়া কিছু বিশেষ ক্যারেক্টার ব্যবহার করা হয়, যাদের এস্কেপ সিকোয়েন্স বলে। এগুলো স্ক্রিনে দেখা যায় না কিন্তু নির্দিষ্ট কাজ করে।
সংজ্ঞা (Definition): এস্কেপ সিকোয়েন্স (Escape Sequence) হলো ব্যাকস্ল্যাশ () দিয়ে শুরু হওয়া বিশেষ ক্যারেক্টার যা কম্পাইলারকে সাধারণ ক্যারেক্টারের পরিবর্তে বিশেষ নির্দেশ (যেমন নতুন লাইন বা ট্যাব) প্রদান করে।
| এস্কেপ সিকোয়েন্স | নাম | কাজ |
|---|---|---|
\n |
New Line | কার্সরকে নতুন লাইনের শুরুতে নিয়ে যায় |
\t |
Horizontal Tab | কার্সরকে এক ট্যাব (সাধারণত ৪ বা ৮ স্পেস) ডানে সরায় |
\b |
Backspace | কার্সরকে এক ঘর বামে সরায় (আগের অক্ষর মুছে ফেলার মতো) |
\" |
Double Quote | আউটপুটে ডাবল কোটেশন (") প্রদর্শন করতে |
\\ |
Backslash | আউটপুটে ব্যাকস্ল্যাশ () প্রদর্শন করতে |
\0 |
Null Character | স্ট্রিং-এর সমাপ্তি নির্দেশ করতে (মেমোরিতে ব্যবহৃত হয়) |
৩. ইনপুট ফাংশন: scanf()
ব্যবহারকারীর কাছ থেকে ডেটা ইনপুট নেওয়ার জন্য scanf() ফাংশন ব্যবহার করা হয়।
গঠন (Syntax):
scanf("Control String", &Variable_Name);
এখানে সবচেয়ে গুরুত্বপূর্ণ বিষয় হলো ভেরিয়েবলের নামের আগে & (Ampersand) চিহ্ন ব্যবহার করা।
& বা Address of Operator কেন ব্যবহার করা হয়?
যখন আমরা একটি ভেরিয়েবল ডিক্লেয়ার করি (যেমন int a;), তখন র্যামের (RAM) মধ্যে একটি নির্দিষ্ট ঠিকানায় বা অ্যাড্রেসে মেমোরি বরাদ্দ হয়। scanf ফাংশনকে বলে দিতে হয় যে, কি-বোর্ড থেকে নেওয়া মানটি মেমোরির ঠিক কোন ঠিকানায় গিয়ে জমা হবে।
উপরের চিত্রে লক্ষ্য করুন, ভেরিয়েবল a-এর মান ১০ এবং এর মেমোরি অ্যাড্রেস ১০০৪। &a মূলত এই ১০০৪ ঠিকানাটিকে নির্দেশ করে। তাই scanf এ & না দিলে প্রোগ্রাম জানবে না মানটি কোথায় রাখতে হবে, ফলে প্রোগ্রাম ভুল কাজ করবে বা ক্র্যাশ করবে।
গুরুত্বপূর্ণ (Important):
- সাধারণ ভেরিয়েবল (int, float, char) ইনপুট নেওয়ার সময় & দিতেই হবে।
- কিন্তু String (char array) ইনপুট নেওয়ার সময় & দেওয়ার প্রয়োজন নেই। কারণ অ্যারে-এর নাম নিজেই তার প্রথম উপাদানের ঠিকানা নির্দেশ করে।
- scanf("%d", &age); (সঠিক)
- scanf("%s", name); (সঠিক, এখানে & নেই)
৪. অক্ষর ও স্ট্রিং ইনপুট-আউটপুট (Advanced I/O)
printf এবং scanf ছাড়াও সি ল্যাঙ্গুয়েজে অক্ষর (character) এবং স্ট্রিং (string) নিয়ে কাজ করার জন্য কিছু বিশেষ ফাংশন আছে।
ক্যারেক্টার I/O: getchar() ও putchar()
getchar(): কি-বোর্ড থেকে একটি মাত্র অক্ষর ইনপুট নেয়। এন্টার (Enter) চাপার পর এটি কাজ করে।putchar(): স্ক্রিনে একটি মাত্র অক্ষর প্রদর্শন করে।
স্ট্রিং I/O: gets() ও puts()
এটি পরীক্ষার জন্য খুবই গুরুত্বপূর্ণ। অনেক সময় scanf দিয়ে স্ট্রিং ইনপুট নিতে গেলে সমস্যা হয়।
scanf() বনাম gets() এর পার্থক্য:
| বৈশিষ্ট্য | scanf("%s", str) |
gets(str) |
|---|---|---|
| স্পেস গ্রহণ | স্পেস (Space) পেলে ইনপুট নেওয়া বন্ধ করে দেয়। | স্পেস সহ পুরো লাইন ইনপুট নিতে পারে। |
| ব্যবহার | শুধু একটি শব্দ নেওয়ার জন্য উপযুক্ত। | পুরো বাক্য (Sentence) নেওয়ার জন্য উপযুক্ত। |
| উদাহরণ | ইনপুট: "Abdul Karim" মেমোরিতে জমা হবে: "Abdul" |
ইনপুট: "Abdul Karim" মেমোরিতে জমা হবে: "Abdul Karim" |
পরীক্ষার টিপস (Exam Tip): যদি উদ্দীপকে কারো "পুরো নাম" বা "ঠিকানা" ইনপুট নেওয়ার কথা বলা থাকে, তবে অবশ্যই gets() ফাংশন ব্যবহার করবে। কারণ নামে বা ঠিকানায় স্পেস থাকে যা scanf পড়তে পারে না।
৫. লাইব্রেরি ফাংশন ও হেডার ফাইল
সি ল্যাঙ্গুয়েজে কিছু কাজ (যেমন ইনপুট-আউটপুট, গাণিতিক হিসাব) করার জন্য আগে থেকেই তৈরি করা কিছু ফাংশন থাকে, এদের লাইব্রেরি ফাংশন বলে। এই ফাংশনগুলোর সংজ্ঞা বা প্রোটোটাইপ বিভিন্ন ফাইলে জমা থাকে, যাকে হেডার ফাইল (Header File) বলে।
সংজ্ঞা (Definition): লাইব্রেরি ফাংশন হলো কম্পাইলারের সাথে সরবরাহকৃত পূর্বনির্ধারিত ফাংশন যা প্রোগ্রামে সরাসরি ব্যবহার করা যায়। আর হেডার ফাইল হলো এমন একটি ফাইল (এক্সটেনশন .h) যেখানে এই লাইব্রেরি ফাংশনগুলোর ঘোষণা থাকে।
গাণিতিক ফাংশন: math.h
গাণিতিক জটিল হিসাবের জন্য আমাদের প্রোগ্রামের শুরুতে #include <math.h> লিখতে হয়। নিচে গুরুত্বপূর্ণ কিছু গাণিতিক ফাংশন দেওয়া হলো:
| ফাংশন | কাজ | উদাহরণ | ফলাফল |
|---|---|---|---|
pow(x, y) |
x এর পাওয়ার y নির্ণয় করে ($x^y$) | pow(2, 3) |
8.0 |
sqrt(x) |
x এর বর্গমূল নির্ণয় করে ($\sqrt{x}$) | sqrt(25) |
5.0 |
abs(x) |
পূর্ণসংখ্যার পরম মান (Absolute value) | abs(-10) |
10 |
ceil(x) |
উপরের নিকটতম পূর্ণসংখ্যায় রূপান্তর (Ceiling) | ceil(3.2) |
4.0 |
floor(x) |
নিচের নিকটতম পূর্ণসংখ্যায় রূপান্তর (Floor) | floor(3.9) |
3.0 |
sin(x) |
সাইন এর মান নির্ণয় (x অবশ্যই রেডিয়ানে হবে) | sin(1.57) |
1.0 (approx) |
$$ Radian = Degree \times \frac{\pi}{180} $$
ত্রিকোণমিতিক ফাংশনে (যেমন sin, cos, tan) কোণের মান ডিগ্রিতে দিলে কাজ হবে না, রেডিয়ানে কনভার্ট করে দিতে হবে।
যেমন: sin(30 * 3.1416 / 180)
৬. ব্যবহারিক উদাহরণ (Worked Examples)
উদাহরণ ১: ত্রিভুজের ক্ষেত্রফল নির্ণয় (তিন বাহু দেওয়া থাকলে)
এখানে আমরা sqrt() ফাংশনের ব্যবহার দেখব। সূত্র: $\text{Area} = \sqrt{s(s-a)(s-b)(s-c)}$ যেখানে $s = \frac{a+b+c}{2}$।
#include <stdio.h>
#include <math.h> // sqrt ব্যবহারের জন্য জরুরি
int main() {
double a, b, c, s, area;
printf("Enter 3 sides: ");
scanf("%lf %lf %lf", &a, &b, &c);
s = (a + b + c) / 2;
area = sqrt(s * (s - a) * (s - b) * (s - c));
printf("Area of Triangle = %.2lf\n", area);
return 0;
}
উদাহরণ ২: ফারেনহাইট থেকে সেলসিয়াস রূপান্তর
সূত্র: $C = \frac{F - 32}{1.8}$ বা $C = (F - 32) \times \frac{5}{9}$
#include <stdio.h>
int main() {
float F, C;
printf("Enter Fahrenheit Temperature: ");
scanf("%f", &F);
// মনে রাখবে: C ল্যাঙ্গুয়েজে 5/9 এর মান 0 হয় (পূর্ণসংখ্যা ভাগ)।
// তাই 5.0/9.0 অথবা ভগ্নাংশ ব্যবহার করতে হবে।
C = (F - 32) * (5.0 / 9.0);
printf("Celsius Temperature = %.2f\n", C);
return 0;
}
সংক্ষিপ্ত সারাংশ (Quick Revision):
- ইনপুট ও আউটপুটের জন্য যথাক্রমে scanf() এবং printf() ব্যবহৃত হয়।
- scanf()-এ ভেরিয়েবলের আগে & দিতে হয়, তবে স্ট্রিং-এর ক্ষেত্রে নয়।
- স্পেসসহ স্ট্রিং ইনপুট নিতে gets() ব্যবহার করা ভালো।
- math.h হেডার ফাইলে গাণিতিক ফাংশন (pow, sqrt, sin, cos) থাকে।
- আউটপুট সুন্দর করতে %-5d বা %.2f এর মতো ফরম্যাটিং ব্যবহৃত হয়।
পরিভাষা (Glossary)
| পরিভাষা | অর্থ ও ব্যাখ্যা |
|---|---|
| লাইব্রেরি ফাংশন | সি কম্পাইলারের সাথে দেওয়া পূর্বনির্ধারিত ফাংশন (যেমন printf, sqrt)। |
| হেডার ফাইল | যে ফাইলে লাইব্রেরি ফাংশনগুলোর প্রোটোটাইপ ঘোষণা করা থাকে (যেমন stdio.h)। |
| ফরম্যাট স্পেসিফায়ার | % যুক্ত ক্যারেক্টার যা ডেটার টাইপ ও ফরম্যাট নির্দেশ করে (যেমন %d, %f)। |
| বাফার (Buffer) | ইনপুট বা আউটপুটের সময় ডেটা যেখানে সাময়িকভাবে জমা থাকে। |
| লিঙ্কার (Linker) | কম্পাইলিং-এর একটি ধাপ যা লাইব্রেরি ফাইলকে অবজেক্ট কোডের সাথে যুক্ত করে। |