সি/সি++ প্রোগ্রামিং টিউটোরিয়াল (পর্ব ১০) স্ট্রিং (১)

0
236

সব প্রোগ্রামিং ল্যাঙ্গুয়েজের জন্যই স্ট্রিং হলো একটি অবিচ্ছেদ্য অংশ। বিভিন্ন ল্যাঙ্গুয়েজে যেকোনো ইনপুট সাধারণত স্ট্রিং হিসেবেই নেয়া হয়। এরপর তাকে নির্দিষ্ট ডাটা টাইপে কনভার্ট করা হয়। যেকোনো কিছু প্রিন্ট করতে হলে তা স্ট্রিং হিসেবে প্রিন্ট হয়। অর্থাৎ ইউজার প্রোগ্রামিংয়ে যাই করম্নক না কেনো, তা কোনো না কোনো সময়ে স্ট্রিংয়ে কনভার্ট হয়। এ লেখায় স্ট্রিং সম্পর্কিত বিভিন্ন কাজ নিয়ে আলোচনা করা হয়েছে।

এক স্ট্রিং ভেরিয়েবলের ডাটা অন্য স্ট্রিংয়ের জন্য নির্ধারণ করা
প্রোগ্রামে অনেক সময় একটি স্ট্রিং ভেরিয়েবলের ডাটা তথা স্ট্রিংকে অন্য স্ট্রিং ভেরিয়েবলের জন্য নির্ধারণ করার দরকার হয়। সি ল্যাঙ্গুয়েজে এ কাজের জন্য strcpy নামে একটি লাইব্রেরি ফাংশন আছে, যার প্রটোটাইপ stdio.h ফাইলে বর্ণিত আছে। এটিকে হেডার ফাইলে নিচের মতো করে ডিক্লেয়ার করা হয়েছে।

prototype : char *strcpy(* dest, const char *src)

এখানে যে স্ট্রিং ভেরিয়েবলের ডাটা কপি করা হবে তা src-এর জন্য এবং যে ভেরিয়েবলে কপি করা হবে তা dest-এ পাঠাতে হয়। উদাহরণস্বরূপ :

char n১[৩০]=”rahimn karim”;
char n২[৩০]=”“;
strcpy(n২,n১);

উপরের প্রোগ্রামে হ১ ও হ২ নামে দুটি স্ট্রিং ভেরিয়েবল ডিক্লেয়ার করা হয়েছে, যার প্রথমটিতে কিছু ডাটা অ্যাসাইন করা হয়েছে ও দ্বিতীয়টি খালি রয়েছে। পরে স্ট্রিং কপি করার ফাংশনটি ব্যবহার করে একটি স্ট্রিংয়ের ডাটা অন্য স্ট্রিংয়ে কপি করা হয়েছে। এখানে খেয়াল করলে দেখা যাবে, ফাংশনের ভেতরে হ২-এর পর হ১ লেখা হয়েছে, যা প্রটোটাইপের ফরম্যাট অনুযায়ী কাজ করবে।
একটি স্ট্রিংয়ে মোট

ক্যারেক্টার সংখ্যা বের করা

কোনো প্রোগ্রামে স্ট্রিংয়ের অনেক ধরনের কাজের মাঝে একটি হলো স্ট্রিংয়ে মোট কতগুলো ক্যারেক্টার আছে তা বের করা। যারা প্রোগ্রামিং কন্টেস্ট করেন তাদের জন্য এটি খুবই সাধারণ একটি সমস্যা। আর এ ধরনের সমস্যার বাসত্মব উদাহরণ হলো, কোনো ওয়ার্ড প্রসেসর যেমন মাইক্রোসফট ওয়ার্ডে যখন কোনো টেক্সট ফাইল ওপেন করা হয়, তখন একদম নিচে ওই ফাইলের মোট ক্যারেক্টার সংখ্যা দেখায়। শুধু তাই নয়, ইউজার যদি একটি নির্দিষ্ট প্যারা সিলেক্ট করে, তাহলে সিলেক্ট করা প্যারায় কতগুলো ক্যারেক্টার আছে তাও দেখানো হয়। যাই হোক, এ ধরনের সমস্যা সমাধানের অনেক উপায় আছে। তবে এখানে সবচেয়ে সহজ উপায়টি দেখানো হয়েছে। সি-Z strlen নামে একটি লাইব্রেরি ফাংশন আছে। এর কাজ হলো কোনো স্ট্রিংয়ের মোট লেংথ বের করা। এটি কীভাবে ব্যবহার করা হয় ও কীভাবে এটি ব্যাবহার করে স্ট্রিংয়ের মোট ক্যারেক্টার সংখ্যা বের করা যায়, তা নিচে একটি ছোট উদাহরণের মাধ্যমে দেখানো হলো।

char _address[]=চ১৪১,১৪২ love road, tejgaon”
int length=strlen(_address);

প্রথমে একটি স্ট্রিং ভেরিয়েবল ডিক্লেয়ার করে তাতে ভ্যালু হিসেবে একটি অ্যাড্রেস রাখা হয়েছে। ওই স্ট্রিংয়ে কতগুলো ক্যারেক্টার আছে। তা গণনা করার জন্য strlen() ফাংশনটি ব্যবহার করা হয়েছে। মনে রাখতে হবে strlen() ফাংশন সবসময় প্যারামিটার হিসেবে একটি স্ট্রিং নেয় এবং সবসময় একটি ইন্টিজার ভ্যালু রিটার্ন করে, এই ভ্যালুটি হলো ওই স্ট্রিংয়ের মোট ক্যারেক্টার সংখ্যা। তাই উপরের অ্যাড্রেসের মোট ক্যারেক্টার সংখ্যা রাখার জন্য length নামে একটি ইন্টিজার ডিক্লেয়ার করা হয়েছে এবং এর ভ্যালু হিসেবে strlen() ফাংশনের রিটার্ন করা ভ্যালু নির্ধারণ করা হয়েছে। তাহলে length ভেরিয়েবলে যে ভ্যালু পাওয়া যাবে তা-ই হলো অ্যাড্রেসের মোট ক্যারেক্টার সংখ্যা। এভাবে লাইব্রেরি ফাংশন ব্যবহার করে যেকোনো স্ট্রিংয়ের মোট ক্যারেক্টার সংখ্যা বের করা যায়। তবে আগেই বলা হয়েছে, এটি সবচেয়ে সহজ উপায়। তাই এভাবে গণনা করলে স্ট্রিংয়ের সব ক্যারেক্টারকেই বিবেচনা করা হবে। অর্থাৎ একটি স্ট্রিংয়ে যদি অনেক স্পেস থাকে, তাহলে তাকেও ক্যারেক্টার হিসেবে দেখা হবে। এখন ইউজার যদি চায় যে স্পেসকে গণনা করা হবে না, অথবা শুধু অক্ষরকে ধরা হবে কোনো সংখ্যাকে বিবেচনা করা হবে না, তখন এভাবে ক্যারেক্টার গণনা করলে হবে না। সেজন্য অন্য উপায়ে ক্যারেক্টার সংখ্যা বের করতে হবে। যার একটি উপায় হলো, কোনো স্ট্রিংয়ের সব ক্যারেক্টারের মাঝে একটি একটি করে ক্যারেক্টার নিয়ে প্রথমে দেখা হবে সেটি গণনা করা যায় কি না। এরপর তাকে বিবেচনা করা হবে। একটি ছোট উদাহরণ নিচে দেয়া হলো।

char _address[]=”141,142 love road, tejgaon”
int count=0;
char c=’’;
for(int i=0;i<strlen(_address);i++)
{
c=_address[i];
if((c>=65&&c<=90)||(c>=97&&c<=122))
count++;
}

এখানে স্ট্রিং হিসেবে আগের উদাহরণের অ্যাড্রেসকে ব্যবহার করা হয়েছে। কিন্তু আগের উদাহরণে সব ক্যারেক্টারকে গণনা করা হলেও এবারে শুধু অ-ত এবং a-z কে গণনা করা হবে, অন্য কোনো ক্যারেক্টার থাকলে তাকে ক্যারেক্টার হিসেবে বিবেচনা করা হবে না। প্রথমে কাউন্ট নামে একটি ইন্টিজার ডিক্লেয়ার করা হয়েছে ক্যারেক্টার গণনা করার জন্য। তারপর সি নামে একটি টেম্পরারি ক্যারেক্টার ভেরিয়েবল ডিক্লেয়ার করা হয়েছে। এবার একটি ফর লুপে অ্যাড্রেসের সব ক্যারেক্টার চেক করা হয়েছে। এখানে ফর লুপের কন্ডিশন হলো strlen(_address); অর্থাৎ অ্যাড্রেসে যতগুলো ক্যারেক্টার আছে ফর লুপটি ততবার চলবে। তারপর প্রতিবার অ্যাড্রেস স্ট্রিংয়ের ক্যারেক্টারকে সি ভেরিয়েবলের মাঝে নিয়ে তা চেক করা হয়েছে। চেকিং রভ-বষংব দিয়ে করা হয়েছে এবং এখানে কন্ডিশন হিসেবে সরাসরি আস্কি ভ্যালু ব্যবহার হয়েছে। আমরা জানি অ-ত এর আস্কি ভ্যালু হলো ৬৫-৯০ এবং a-z এর আস্কি ভ্যালু হলো ৯৭-১২২। তাই ক্যারেক্টার সি-এর আস্কি ভ্যালু যদি কন্ডিশনের মাঝে পরে শুধু তাহলেই কাউন্ট ভেরিয়েবলের মান ১ করে বাড়বে। আর ফর লুপ শেষে কাউন্ট ভেরিয়েবলের মানই হলো মোট ক্যারেক্টার সংখ্যা। এটি হলো ক্যারেক্টার গণনার একটি কাস্টম কন্ডিশন। ইউজার যদি চান যে সব নিউমেরিক অক্ষরকেও ক্যারেক্টার হিসেবে কাউন্ট করতে হবে, তাহলে রভ-বষংব-এর কন্ডিশন সেভাবে ঠিক করে দিতে হবে। এখানে যদিও আস্কি ভ্যালু দিয়ে কন্ডিশন চেক করা হয়েছে।

ইউজার চাইলে সরাসরি ক্যারেক্টার দিয়েও চেক করতে পারেন। সে ক্ষেত্রে কন্ডিশন এরকম করে লিখতে হবে : if((c>=’a’&&c<=’z’)||(c>=’A’&&c<=’Z’)। ইউজারের বোঝার সুবিধার্থে প্রথমে আস্কি ভ্যালু দিয়ে কন্ডিশন দেয়া হয়েছে। কারণ প্রথমেই ক্যারেক্টার দিয়ে কন্ডিশন দেয়া হলে মনে প্রশ্ন জাগতে পারত যে >=a Ges <=z দিয়ে কী বোঝানো হচ্ছে। আসলে আমরা জানি সব ক্যারেক্টারকে প্রোগ্রাম আস্কি ভ্যালু দিয়ে চেনে। তাই ইউজার যদি সরাসরি ক্যারেক্টার দেন তাহলেও প্রোগ্রাম তাকে আসলে আস্কি ভ্যালুতে কনভার্ট করে নেবে। আর সরাসরি আস্কি ভ্যালু দিয়ে সেখানে কনভার্টের কোনো প্রশ্ন নেই। তবে খেয়াল রাখতে হবে, সিঙ্গেল কোটের (‘’) মাঝে ক্যারেক্টার লিখতে হবে। তাই লক্ষ করলে দেখা যাবে উপরের কন্ডিশনে ক্যারেক্টারকে সিঙ্গেল কোটের মাঝে লেখা হয়েছে, কিন্তু আস্কি ভ্যালুকে কোনো কোটের মাঝে লেখা হয়নি। কারণ সিঙ্গেল কোটেশনের মাঝে যাই লেখা হোক না কেনো তা ক্যারেক্টার হিসেবে বিবেচনা হবে, আর ডাবল কোটের মাঝে লিখলে তাকে স্ট্রিং হিসেবে দেখা হবে। সাধারণ এনকোডিং মেথডে ২৫৫টি ক্যারেক্টার আছে। অর্থাৎ তাদের আস্কি ভ্যালু ০-২৫৫। এ সাধারণ ক্যারেক্টারের মাঝে ইংরেজি লেটারসহ নিউমেরিক সংখ্যাও আছে। ইউজার চাইলে এ আস্কি ভ্যালুগুলো ইন্টারনেট থেকে দেখতে পারেন। তবে ইংরেজি ল্যাঙ্গুয়েজ ছাড়া যদি অন্য কোনো ল্যাঙ্গুয়েজ ব্যবহার করা হয়, সে ক্ষেত্রে আর সাধারণ এনকোডিং থাকে না। তখন সেটি ইউনিকোডে এনকোড করা হয় যেখানে আস্কি ক্যারেক্টার ০-২৩২টি।

একটি উত্তর ত্যাগ