আধুনিক সি ++ এটিকে অতি সাধারণ করে তোলে।
সি ++ 20
সি ++ ২০ টি পরিচয় করিয়ে std::format
দেয় যা আপনাকে ঠিক এটি করতে দেয়। এটি পাইথনের মতো প্রতিস্থাপন ক্ষেত্রগুলি ব্যবহার করে :
#include <iostream>
#include <format>
int main() {
std::cout << std::format("Hello {}!\n", "world");
}
সম্পূর্ণ ডকুমেন্টেশন পরীক্ষা করে দেখুন ! এটি জীবনের বিশাল মানের উন্নতি।
সি ++ 11
সঙ্গে সি ++ 11 এর std::snprintf
, এই ইতিমধ্যে একটি বেশ সহজ এবং নিরাপদ কাজের হয়ে ওঠে।
#include <memory>
#include <string>
#include <stdexcept>
template<typename ... Args>
std::string string_format( const std::string& format, Args ... args )
{
size_t size = snprintf( nullptr, 0, format.c_str(), args ... ) + 1; // Extra space for '\0'
if( size <= 0 ){ throw std::runtime_error( "Error during formatting." ); }
std::unique_ptr<char[]> buf( new char[ size ] );
snprintf( buf.get(), size, format.c_str(), args ... );
return std::string( buf.get(), buf.get() + size - 1 ); // We don't want the '\0' inside
}
উপরের কোড স্নিপেট সিসি ০.০ এর অধীনে লাইসেন্সযুক্ত ।
লাইন দ্বারা লাইন ব্যাখ্যা:
লক্ষ্য:char*
ব্যবহার করে একটি লিখুনstd::snprintf
এবং তারপরে এটিকে রূপান্তর করুনstd::string
।
প্রথমে, আমরা একটি বিশেষ শর্তটি ব্যবহার করে চর অ্যারের পছন্দসই দৈর্ঘ্য নির্ধারণ করি snprintf
। সিপ্রেফারেন্স.কম থেকে :
ফেরত মূল্য
[...] যদি বুফ_সাইজ সীমাবদ্ধতার কারণে ফলাফলটি স্ট্রিংটি কেটে ফেলা হয় তবে ফাংশনটি মোট অক্ষরের সংখ্যা প্রদান করে (শূন্যকরণ নাল-বাইট সহ নয়) যা লিখিত হত, যদি সীমাটি আরোপিত না হয়।
এর অর্থ হ'ল কাঙ্ক্ষিত আকারটি হ'ল অক্ষরের সংখ্যা এবং এক , যাতে নাল-টার্মিনেটর অন্য সমস্ত অক্ষরের পরে বসবে এবং এটি আবার স্ট্রিং কনস্ট্রাক্টর দ্বারা কেটে ফেলা যায়। @ ইলেক্সক 7 মন্তব্যগুলিতে এই বিষয়টি ব্যাখ্যা করেছেন।
size_t size = snprintf( nullptr, 0, format.c_str(), args ... ) + 1;
snprintf
কোনও ত্রুটি দেখা দিলে একটি নেতিবাচক নম্বর ফিরিয়ে দেবে, সুতরাং আমরা ফর্ম্যাটটি পছন্দ মতো কাজ করেছি কিনা তা পরীক্ষা করে দেখি। মন্তব্যগুলিতে @ ইড দ্বারা নির্দেশিত হিসাবে এটি না করার ফলে নীরব ত্রুটি বা বিশাল বাফারের বরাদ্দ হতে পারে।
if( size <= 0 ){ throw std::runtime_error( "Error during formatting." ); }
এর পরে, আমরা একটি নতুন অক্ষর অ্যারে বরাদ্দ করি এবং এটি এটিকে নির্ধারণ করি std::unique_ptr
। এটি সাধারণত পরামর্শ দেওয়া হয়, কারণ আপনাকে delete
এটি আর ম্যানুয়ালি করতে হবে না ।
নোট করুন যে এটি unique_ptr
ব্যবহারকারী-সংজ্ঞায়িত প্রকারের সাথে বরাদ্দ দেওয়ার নিরাপদ উপায় নয় কারণ আপনি যদি নির্মাণকর্তা কোনও ব্যতিক্রম ছুঁড়ে ফেলেন তবে মেমরিটি হ্রাস করতে পারবেন না!
std::unique_ptr<char[]> buf( new char[ size ] );
এর পরে, আমরা অবশ্যই snprintf
এটির উদ্দেশ্যে ব্যবহারের জন্য ব্যবহার করতে পারি এবং বিন্যাসিত স্ট্রিংটি লিখতে পারি char[]
।
snprintf( buf.get(), size, format.c_str(), args ... );
শেষ পর্যন্ত, আমরা std::string
এটিকে থেকে একটি নতুন তৈরি এবং ফিরিয়ে দিই, শেষে নাল-টার্মিনেটর বাদ দেওয়ার বিষয়টি নিশ্চিত করে।
return std::string( buf.get(), buf.get() + size - 1 );
আপনি এখানে কর্মের একটি উদাহরণ দেখতে পারেন ।
আপনি যদি std::string
তর্ক তালিকায় ব্যবহার করতে চান তবে এই টুকরোটিটি একবার দেখুন ।
ভিজ্যুয়াল স্টুডিও ব্যবহারকারীদের জন্য অতিরিক্ত তথ্য :
এই উত্তরে যেমন বর্ণনা করা হয়েছে , মাইক্রোসফ্ট (হ্যাঁ, ছাড়া ) এর নতুন নামকরণ std::snprintf
করেছে । এমএস এটিকে আরও অবহেলিত হিসাবে সেট করে এবং পরিবর্তে ব্যবহারের পরামর্শ দেয় তবে যাইহোক বাফারটিকে ফর্ম্যাট করা আউটপুটের তুলনায় শূন্য বা তার থেকে ছোট হিসাবে গ্রহণ করবে না এবং যদি ঘটে তবে আউটপুটগুলির দৈর্ঘ্য গণনা করবে না। তাই সংকলনের সময় হ্রাসকারী সতর্কতা থেকে মুক্তি পাওয়ার জন্য, আপনি ফাইলের শীর্ষে নীচের লাইনটি সন্নিবেশ করতে পারেন যার ব্যবহার রয়েছে :_snprintf
std::
_snprintf_s
_snprintf_s
_snprintf
#pragma warning(disable : 4996)
সর্বশেষ ভাবনা
এই প্রশ্নের অনেকগুলি উত্তর সি ++ 11-এর আগে লেখা হয়েছিল এবং নির্দিষ্ট বাফার দৈর্ঘ্য বা বর্ণগুলি ব্যবহার করেছিল। আপনি সি ++ এর পুরানো সংস্করণগুলিতে আটকে না থাকলে আমি এই সমাধানগুলি ব্যবহার করার পরামর্শ দেব না। আদর্শভাবে, সি ++ 20 পথে যান।
কারণ এই উত্তরের সি ++ ১১ টি সমাধান টেমপ্লেট ব্যবহার করে, এটি যদি অনেক বেশি ব্যবহৃত হয় তবে কোডটি বেশ খানিকটা তৈরি করতে পারে। তবে, আপনি যদি বাইনারিগুলির জন্য খুব সীমিত জায়গার পরিবেশের জন্য বিকাশ না করেন তবে এটি কোনও সমস্যা হবে না এবং স্বচ্ছতা এবং সুরক্ষা উভয় ক্ষেত্রেই অন্যান্য সমাধানগুলির তুলনায় এটি একটি বৃহত উন্নতি।
স্থানটির দক্ষতা যদি অতি গুরুত্বপূর্ণ হয় তবে ভার্জ এবং ভার্সনপ্রিন্টফ সহ এই দুটি সমাধান কার্যকর হতে পারে।
স্থির বাফার দৈর্ঘ্যের কোনও সমাধান ব্যবহার করবেন না , এটি কেবল সমস্যার জন্য জিজ্ঞাসা করছে।
boost::format
(কেনেটিমের সমাধান এখানে ব্যবহার করে )।boost::format
ইতিমধ্যে সি ++ স্ট্রিম অপারেটরগুলিকেও সমর্থন করে! উদাহরণ:cout << format("helloworld. a=%s, b=%s, c=%s") % 123 % 123.123 % "this is a test" << endl;
।boost::format
কোডের সর্বনিম্ন লাইন রয়েছে ... পিয়ার-পর্যালোচনা করা হয় এবং সি ++ স্ট্রিমগুলির সাথে দুর্দান্তভাবে সংহত করে।