ইনপুট এবং আউটপুট স্ট্রিম (Input & Output with Streams)
এখানকার এই কনভেয়র বেল্ট মডেল (The Conveyor Belt Model)
কিছুক্ষণের জন্য printf এবং scanf-এর কথা ভুলে যান। সি++ (C++) মূলত আপনার সামনে স্ট্রিম (streams) নামের একটি অত্যন্ত দারুণ বা বিউটিফুল (beautiful) আই/ও (I/O) অ্যাবস্ট্রাকশন (abstraction) নিয়ে এসেছে। কোনো কারখানার তৈরি একটি কনভেয়র বেল্টের (conveyor belt) কথা চিন্তা করুন:
cout— এটি হলো একটি আউটপুট বেল্ট (output belt)। আপনি<<-এর সাহায্যে এর ওপরে বিভিন্ন আইটেম রাখতে (place) পারেন, এবং এগুলো স্ক্রিনের দিকে গড়িয়ে পড়বে (roll out)।cin— এটি হলো একটি ইনপুট বেল্ট (input belt)। এক্ষেত্রে কীবোর্ড (keyboard) থেকে বিভিন্ন আইটেম আসবে বা পৌঁছাবে, এবং আপনি>>-এর সাহায্যে সেগুলোকে তুলে (pick) নেবেন।cerr— এটি হলো জরুরি বেল্ট (emergency belt)। এখানকার বিভিন্ন এরর বা ত্রুটির মেসেজগুলো (Error messages) মূলত এখানেই এসে থাকে — এগুলো মূলত আনবাফারড (unbuffered) হয়ে থাকে, যার ফলে এগুলো খুব দ্রুত বা তাৎক্ষণিকভাবে (immediately) স্ক্রিনে ভেসে ওঠে।
এই স্ট্রিমগুলোর (streams) প্রধান সৌন্দর্য বা বিউটি (beauty) হলো এদের টাইপ সেফটি (type safety)। যেমন printf("%d", x)-এর ক্ষেত্রে যদি আপনি কোনো ভুল ফরম্যাট স্পেসিফায়ার (format specifier) ব্যবহার করেন, তবে তা বিভিন্ন বাগের (bugs) কারণ হয়ে দাঁড়াবে, কিন্তু cout << x সব সময়ই x-এর টাইপ বা ধরনটি বুঝতে পারে এবং সেটিকে একদম সঠিকভাবে বা correctly প্রিন্ট (prints) করে।
cout-এর সাথে বেসিক আউটপুট (Basic Output)
cin ব্যবহার করে ইনপুট পড়া বা Reading Input
cin >> মূলত একবারে শুধু একটি "টোকেন (token)"-ই পড়তে (reads) পারে — এটি যেকোনো হোয়াইটস্পেসে (whitespace) (যেমন স্পেস, ট্যাব, নিউলাইন) এসেই থেমে যায়। এর এই পদ্ধতিটি যেকোনো একক শব্দ বা নাম্বারের (numbers) ক্ষেত্রে দারুণ, কিন্তু আপনার যখন স্পেসসহ (with spaces) একটি সম্পূর্ণ লাইনের (full line) প্রয়োজন পড়বে তখন এটি ব্যর্থ (falls apart) হবে।
আর ঠিক এমন জায়গাতেই getline(cin, str)-এর ব্যবহারটি চলে আসে। এটি স্পেস (spaces) সহ নিউলাইন বা এন্টারের আগ পর্যন্ত সবকিছুই (everything until the newline) পড়তে (reads) পারে।
cin >> বনাম বা vs getline
cin >> মূলত যেকোনো হোয়াইটস্পেসে (whitespace) গিয়ে থেমে যায়। তাই সম্পূর্ণ লাইনের (full lines) ক্ষেত্রে getline(cin, str) ব্যবহার করুন। কিন্তু এই cin >> এবং getline-কে একসাথে ব্যবহার করাটা মূলত এক ধরনের সূক্ষ্ম বা স্ন্যিকি নিউলাইন বাগের (sneaky newline bug) জন্ম দিতে পারে — cin >>-এর কাজ শেষ হলে বাফারে (buffer) একটি '\n' অবশিষ্ট (leftover) বা বেঁচে থাকে, আর এর পরপরই ঠিক ওই getline-টি এসে সেই বেঁচে যাওয়া অবশিষ্ট বা খালি লাইনটিকে (empty line) পড়ে নেয়। সমাধান বা Fix: এই ধরনের লুকিয়ে থাকা নিউলাইনটিকে (lurking newline) ফেলে (discard) দিতে এই দুইটির মাঝখানে মূলত cin.ignore()-কে কল (call) করুন।iomanip ব্যবহার করে ফরম্যাটেড আউটপুট (Formatted Output)
আপনার কি কোনো টেবিলের কলামগুলোকে (columns) সাজানোর (line up) প্রয়োজন? ডেসিমাল (decimal) বা দশমিকের স্থানগুলোকে (places) নিয়ন্ত্রণ করার দরকার? কিংবা নাম্বারের (numbers) আগে শূন্য বসানোর (Pad with zeros) দরকার? এর এই <iomanip> হেডারটি (header) মূলত আপনার জন্য এই সমস্ত কাজেরই সমাধান নিয়ে এসেছে। এটি ম্যানিপুলেটরগুলো (manipulators) প্রদান করে থাকে — এগুলো হলো এমন কিছু বিশেষ অবজেক্ট (special objects), যা আপনি স্ট্রিমে ইনসার্ট (insert) করে তার পরবর্তী আইটেমটিকে কীভাবে ফরম্যাট বা সাজানো (formatted) হবে তা নির্ধারণ করে দিতে পারেন।
setw(n)— এটি মূলত পরবর্তী আউটপুট ফিল্ডের (output field) সর্বনিম্ন প্রস্থ বা প্রস্থের (minimum width) পরিমাণ নির্ধারণ করে দেয়setprecision(n)— এটি মূলত ঠিক কতগুলো সংখ্যা (digits) দেখা যাবে তা নিয়ন্ত্রণ বা কন্ট্রোল করেfixed— এটি মূলত ফিক্সড-পয়েন্ট নোটেশনগুলো (fixed-point notation) বা বিভিন্ন সাধারণ ডেসিমাল সংখ্যা (scientific নয়) প্রদর্শনে ব্যবহার করা হয়left/right— এটি মূলত এর ফিল্ডের ওই প্রস্থের ভেতরেই এর অ্যালাইনমেন্ট (alignment) বা সজ্জা ঠিক করে দেয়setfill(c)— এটি মূলত বিভিন্ন অতিরিক্ত স্পেসগুলোকে (spaces) খালি না রেখে নির্দিষ্ট কোনো অক্ষর বা ক্যারেক্টার c দিয়ে ওই জায়গাটিকে পূরণ (fill) করে দেয়
iomanip-এর সাহায্যে ফরম্যাটিং (Formatting)
স্ট্রিং স্ট্রিমগুলো (String Streams) — কোনো প্রকার I/O ছাড়াই স্ট্রিমগুলো (Streams Without I/O)
কখনো কখনো হয়তো আপনি কোনো একটি ফরম্যাট বা সাজানো স্ট্রিংকে (formatted string) প্রিন্ট না করেই (without) সেটি তৈরি বা নির্মাণ (build) করতে চান। এই <sstream>-এ থাকা stringstream-টি মূলত এমন একটি স্ট্রিম (stream) যা মেমোরিতে (memory) একটি string থেকে তার ডেটা পড়তে (reads) এবং সেটিতে তার ডেটা লিখতে (writes) পারে। এটিকে আপনি অনেকটা এমন একটি কনভেয়র বেল্টের (conveyor belt) মতো কল্পনা করতে পারেন, যা নিজেই নিজের ওপর ঘুরে আসে বা বৃত্ত তৈরি (loops back) করে — যেখানে আপনি এর ওপর বিভিন্ন জিনিস রাখেন (put things), এবং এরপর তার একত্র করা (assembled) ফলাফলটিকে একটি একক স্ট্রিং (single string) হিসেবে তুলে (take off) নেন।
বিভিন্ন ধরনের স্ট্রিং পার্সিং (parsing strings) বা যেকোনো জটিল আউটপুট (complex output) তৈরির ক্ষেত্রে এটি খুব অবিশ্বাস্যভাবে কার্যকর (incredibly handy) বা হ্যান্ডি।
স্ট্রিং স্ট্রিম (String Streams)
ইওএফ বা EOF (End Of File) পর্যন্ত পড়া বা Reading Until EOF
এখানকার একটি সাধারণ প্যাটার্ন (common pattern) হলো ইনপুটে যতক্ষণ পর্যন্ত না সবকিছু শেষ (nothing left) হয়ে যাচ্ছে, ততক্ষণ পর্যন্ত শুধু পড়তেই (reading) থাকা — এটি মূলত বিভিন্ন প্রতিযোগিতামূলক প্রোগ্রামিংগুলোতে (competitive programming) বা যেকোনো পাইপযুক্ত ফাইলগুলো (piped files) প্রসেস করার ক্ষেত্রে খুব দারুনভাবে কাজে আসে। cin >> variable-এর সাহায্যে আপনি চাইলেই এক্ষেত্রে একটি লুপ (loop) তৈরি করতে পারবেন — কারণ ইনপুটের ওই স্ট্রিমটি (stream) যখন শেষ বা ফুরিয়ে (exhausted) যায়, তখন এটি মূলত বিভিন্ন রেফারেন্সগুলোকে এমন একটি false রূপে রিটার্ন (returns) করে।