C স্ট্রিং : ইনপুট আউটপুট

আজকে আমরা আলোচনা করব স্ট্রিং কিভাবে ইনপুট নিতে হয় এবং কিভাবে একটি স্ট্রিংকে আউটপুট দিতে হয়।



C স্ট্যান্ডার্ড ইনপুট ফাংশন scanf() এবং আউটপুট ফাংশন printf() ব্যবহার করে সরাসরি স্ট্রিং ইনপুট আউটপুট করা যায়। এছাড়াও ANSI C স্ট্যান্ডার্ড লাইব্রেরী তে স্ট্রিং ইনপুট এর জন্য gets() ও fgets() ফাংশন এবং আউটপুট এর জন্য puts() ও fputs() ফাংশন রয়েছে। এছাড়াও বেশ কিছু উপায়ে স্ট্রিং ইনপুট নেওয়া যায় যার সংক্ষিপ্ত আলোচনা এখানে করা হবে।

স্ট্রিং ইনপুট


  • scanf() ব্যবহার করে


scanf() এর মাধ্যমে স্ট্রিং ইনপুট নেবার জন্য %s টাইপ স্পেসিফিকেশন ব্যবহার করা হয়। আর আর্গুমেন্ট হিসেবে স্ট্রিং এর নামটি ব্যবহার করা হয়। মনে রাখতে হবে যে, scanf() এর আর্গুমেন্ট এর সাথে সচরাচর যেরকম & ব্যবহার করা হয়, স্ট্রিং এর ক্ষেত্রে স্ট্রিং এর নামের আগে কখনোই & ব্যবহার করা হয় না।

উদাহরণস্বরূপ, আমরা str নামের একটি স্ট্রিং ভ্যারিয়েবল (char array) ডিক্লেয়ার করি যাতে ২০ ক্যারেকটার দৈর্ঘ্যের একটি স্ট্রিং রাখা যাবে। এরপর আমরা তাতে scanf() ব্যবহার করে ইনপুট নিবো।

char str[21];

scanf("%s", str);

এই কোড দ্বারা আমরা ২০ ক্যারেকটার দৈর্ঘ্যের একটি স্ট্রিং ইনপুট নিতে পারবো। তবে তাতে কোন white space ক্যারেকটার (যেমন, blank space বা new line ক্যারেকটার) থাকতে পারবে না। এর কারণ হচ্ছে white space ক্যারেকটারকে scanf() সেপারেটর হিসেবে ধরে নেয়। যখনই ইনপুট এ কোন white space ক্যারেকটার পায়, তখনই সে যে ভ্যারিয়েবল এ ইনপুট নিচ্ছিলো তাতে ইনপুট নেওয়া বন্ধ করে দেয় এবং আর্গুমেন্ট লিস্টে পরবর্তী কোন ভ্যারিয়েবল এড্রেস থাকলে তাতে ইনপুট নেওয়া শুরু করে।

অর্থাৎ,  উপরের কোডে আমরা যদি "Programming" স্ট্রিং টি ইনপুট দিই তাহলে ঠিকমতো ইনপুট হবে কিন্তু, "I love C string" স্ট্রিংটি ইনপুট নিলে শুধু "I" ইনপুট হবে str স্ট্রিং এ। বাকি "love C string" অংশটি ইনপুট বাফারে রয়ে যাবে যা পরবর্তী কোন ইনপুট ফাংশন কর্তৃক ব্যবহৃত হবে।

তাহলে কি আমরা scanf() ব্যবহার করে সম্পূর্ণ লাইন ইনপুট নিতে পারবো না, যেখানে শব্দগুলোর মধ্যে blank space থাকবে? অবশ্যই পারবো। তবে তার জন্য "%s" স্পেসিফিকেশন এর পরিবর্তে "%[^\n]" স্পেসিফিকেশন ব্যবহার করতে হবে। যেমন, উপরের কোডটিই যদি আমরা এইভাবে লিখি তাহলেই এই সমস্যার সমাধান হয়ে যাবেঃ

char str[21];

scanf("%[^\n]", str);

এই কোডে ইনপুট এ new line ক্যারেকটার '\n' এর আগ পর্যন্ত যা আছে তার পুরোটাই str এ ইনপুট নিবে। তবে অবশ্যই str স্ট্রিং এ পর্যাপ্ত জায়গা থাকতে হবে। পর্যাপ্ত জায়গা না থাকলে স্ট্রিং এর ধারণক্ষমতা পর্যন্ত ইনপুট নেবার পরে, বাকি অংশ ইনপুট বাফারেই রয়ে যাবে, যা পরবর্তী কোন ইনপুট ফাংশন কর্তৃক ব্যবহৃত হবে।

স্ট্রিং সমাপ্তিজ্ঞাপক Null Terminator ('\0') টি scanf() কর্তৃক অটোমেটিকালি স্ট্রিং এর শেষে যুক্ত হয়ে যাবে। 

new line ক্যারেকটার ('\n') কে scanf() ইনপুট না নিয়ে ইনপুট বাফারে রেখে দেয়। তাই পর পর দুইটি স্ট্রিং ইনপুট নেওয়ার সময় সতর্কতা অবলম্বন করতে হবে। নিচের কোডটি রান করেন এবং তাতে "I love C" এবং "this is a string" স্ট্রিং দুইটি কিবোর্ড থেকে ইনপুট দিন। দেখেন রেজাল্ট কি হয়। আপনি কি রেজাল্ট টি ব্যাখ্যা করতে পারবেন?

/* উদাহরণ শুরু */
#include<stdio.h>

int main()
{
char str1[21], str2[21];

scanf("%[^\n]", str1);
scanf("%[^\n]", str2);

printf(str1);
printf(str2);

return 0;
}
/* উদাহরণ শেষ */

  • gets() ও fgets() ব্যবহার করে 


C স্ট্রিং ইনপুট নেওয়ার সবচে সহজ উপায় হচ্ছে gets() ফাংশন ব্যবহার করা। এতটাই সহজ যে, এই ফাংশনের আর্গুমেন্ট হিসেবে স্রেফ স্ট্রিং এর নামটি দিয়ে দিলেই ইনপুট হয়ে যায়। যেমন,

char str[21];

gets(str);

এই কোডটি new line ক্যারেকটার চাপার আগ পর্যন্ত যা ইনপুট বাফারে থাকবে তা str স্ট্রিং এ ইনপুট নিবে। তবে অবশ্যই স্ট্রিং এর ধারণক্ষমতার মধ্যে হতে হবে। যদি ধারণক্ষমতার অতিরিক্ত কোন ক্যারেকটার ইনপুট বাফারে থাকে তবে তা ইনপুট বাফারেই থাকবে যা পরবর্তী কোন ইনপুট ফাংশন কর্তৃক ব্যবহৃত হবে।

স্ট্রিং সমাপ্তিজ্ঞাপক Null Terminator ('\0') টি gets() কর্তৃক অটোমেটিকালি স্ট্রিং এর শেষে যুক্ত হয়ে যাবে। 

new line ক্যারেকটার ('\n') কে gets() ইনপুট নিয়ে নেয়। তাই পর পর দুইটি স্ট্রিং ইনপুট নেওয়ার সময় কোন সমস্যা হয় না। নিচের কোডটি রান করেন এবং তাতে "I love C" এবং "this is a string" স্ট্রিং দুইটি কিবোর্ড থেকে ইনপুট দিন। দেখেন রেজাল্ট কি হয়। আপনি কি রেজাল্ট টি ব্যাখ্যা করতে পারবেন? scanf() এর রেজাল্টের সাথে এর পার্থক্য কি?

/* উদাহরণ শুরু */
#include<stdio.h>

int main()
{
char str1[21], str2[21];

gets(str1);
gets(str2);

puts(str1);
puts(str2);

return 0;
}
/* উদাহরণ শেষ */

[Note : কিছু নিরাপত্তাজনিত কারণে, C এর আধুনিক স্পেসিফিকেশন এ gets() ফাংশন এর ব্যবহার রহিত করা হয়েছে। এই সম্পর্কে বিস্তারিত জানতে ও বুঝতে হলে আপনাকে C ভাষা সম্পর্কে খুব ভালো করে জানতে হবে। তাই, যদিও gets() এখনো ব্যবহার করা যায়, তবে আপনাদের প্রতি পরামর্শ থাকবে gets() ব্যবহার না করে অন্য কোন উপায়ে স্ট্রিং ইনপুট নিতে। C11 স্পেসিফিকেশন এ fget() ব্যবহার করতে বলা হয়েছে। এই ফাংশন সম্পর্কে জানার জন্য এখানে দেখুন।]

স্ট্রিং আউটপুট 

  • printf() ব্যবহার করে


স্ট্যান্ডার্ড আউটপুট ফাংশন printf() ব্যবহার করে দুইভাবে স্ট্রিং আউটপুট দেওয়া যায়। প্রথম পদ্ধতি হচ্ছে, স্ট্রিং এর নামকে সরাসরি printf() এর আর্গুমেন্ট হিসেবে ব্যবহার করে। যেমন,

char str[]= "I love strings.";

printf(str);

এই অংশটি I love strings. স্ট্রিংটি আউটপুট দিবে। তবে এই ক্ষেত্রে যদি আমরা আউটপুট এর পরে একটি new line ক্যারেকটার প্রিন্ট করতে চাই তাহলে আলাদা আরেকটি আউটপুট ফাংশন ব্যবহার করতে হবে।

দ্বিতীয় পদ্ধতি হচ্ছে, %s টাইপ স্পেসিফিকেশন ব্যবহার করে এবং স্ট্রিং এর নামকে সেকেন্ড আর্গুমেন্ট হিসেবে ব্যবহার করে। যেমন,

char str[]="I love strings.";

printf("%s", str);

এই ক্ষেত্রেও I love strings. স্ট্রিংটিই প্রিন্ট হবে। তবে এখানে আমরা প্রয়োজনমত new line ক্যারেকটার সংযোজন করতে পারবো, একাধিক স্ট্রিং একই আউটপুট ফাংশনে আউটপুট দিতে পারবো এবং স্ট্রিং এর সাথে অন্য ডেটা টাইপের ডেটাও আউটপুট দিতে পারবো।

  • puts() ও fputs() ব্যবহার করে


puts() ব্যবহার করে স্ট্রিং আউটপুট দেবার পদ্ধতি অনেকটা printf() ব্যবহার করে আউটপুট দেবার প্রথম পদ্ধতির মত। puts() এর আর্গুমেন্ট হিসেবে স্ট্রিং এর নাম দিয়ে দিলেই স্ট্রিং আউটপুট হয়। যেমন,

char str[]="I love strings.";

puts(str);

তবে printf() এর সাথে পার্থক্য হচ্ছে এখানে অটোমেটিক একটি new line ক্যারেকটার প্রিন্ট হবে। একটি puts() ব্যবহার করে কেবল ১ টি স্ট্রিং আউটপুট দেওয়া যাবে।

fgets() হচ্ছে gets() এর ফাইল আউটপুট ভার্সন। এটি সম্পর্কে বিস্তারিত জানার জন্যে এখানে দেখুন।

স্ট্রিং ইনপুট এর একটি বিকল্প উপায়ঃ

[শুধু মাত্র আগ্রহীরা এটা পড়বেন। এটা সবার পড়ার দরকার নাই।]

স্ট্রিং একটি ক্যারেকটার array। তাই এই array এর একটি ইন্ডেক্সে একটি করে ক্যারেকটার থাকে। আমরা খুব সহজেই ইনপুট বাফার থেকে একটি করে ক্যারেকটার নিয়ে একটি করে ইন্ডেক্সে রাখতে পারি এবং যখন new line ক্যারেকটার পাওয়া যাবে তখন Null terminator ('\0') আমরা ইন্ডেক্সে কপি করবো। যেমন,

char str[21], ch;
int i=0;

for (;;)
{
    ch=getchar();

    if (ch!='\n'&&i<21)
        str[i++]=ch;
    else
    {
        str[i]='\0';
        break;
    }
}

এটি দেখতে বেশ বড় হলেও এটি অনেক ক্ষেত্রে অনেক উপকারে আসে। 

0 comments:

Post a Comment