আমি কীভাবে এক লাইনে একাধিক সি ++ স্ট্রিং সংযুক্ত করতে পারি?


150

সি # এর একটি সিনট্যাক্স বৈশিষ্ট্য রয়েছে যেখানে আপনি 1 লাইনে একসাথে অনেকগুলি ডেটা সংযুক্ত করতে পারেন।

string s = new String();
s += "Hello world, " + myInt + niceToSeeYouString;
s += someChar1 + interestingDecimal + someChar2;

সি ++ এর সমমান কী হবে? আমি যতদূর দেখতে পাচ্ছি, এটি আপনাকে আলাদা আলাদা লাইনে করতে হবে কারণ এটি + অপারেটরের সাথে একাধিক স্ট্রিং / ভেরিয়েবল সমর্থন করে না। এটি ঠিক আছে, তবে ঝরঝরে দেখায় না।

string s;
s += "Hello world, " + "nice to see you, " + "or not.";

উপরের কোডটি একটি ত্রুটি তৈরি করে।


4
অন্য কোথাও ব্যাখ্যা করা হয়েছে, এটি কারণ এটি "অপারেটরের সাথে একাধিক স্ট্রিং / ভেরিয়েবল সমর্থন করে না" - বরং char *আপনি একে অপরের সাথে পয়েন্টার যুক্ত করার চেষ্টা করছেন বলে এটি নয় । এটিই ত্রুটিটি উত্পন্ন করে - কারণ পয়েন্টার সংমিশ্রণ করা অযৌক্তিক। নীচে উল্লিখিত হিসাবে, কমপক্ষে 1 ম অপারেন্ড একটি এ তৈরি করুন std::stringএবং এতে কোনও ত্রুটি নেই।
— আন্ডারস্কোর_

কোন ত্রুটি উত্পাদিত হয়েছিল?
— উলফ

উত্তর:


240
#include <sstream>
#include <string>

std::stringstream ss;
ss << "Hello, world, " << myInt << niceToSeeYouString;
std::string s = ss.str();

হারব সাটার: মনোর ফার্মের স্ট্রিং ফর্ম্যাটটারের এই গুরু অফ দ্য উইক নিবন্ধটি একবার দেখুন


6
এটি ব্যবহার করে দেখুন:std::string s = static_cast<std::ostringstream&>(std::ostringstream().seekp(0) << "HelloWorld" << myInt << niceToSeeYouString).str();
— বাইজান্টিয়ান

42
ss << "বাহ, সি ++ তে স্ট্রিং কনটেন্টেশন চিত্তাকর্ষক" << "বা না" "
— joerl

4
কেবল অন্যভাবে নামকরণের জন্য: একাধিক অ্যাপেন্ড ব্যবহার করুন: স্ট্রিং এস = স্ট্রিং ("অ্যাবসি") app অ্যাপেন্ড ("ডিফ") end
— প্যাট্রিসিও রসি

1
std::stringstream ss; ss << "Hello, world, " << myInt << niceToSeeYouString; std::string s = ss.str();বেশ অনেকটা এক-লাইন
— কোটাউসকাস

74

৫ বছরে কারও উল্লেখ নেই .append?

#include <string>

std::string s;
s.append("Hello world, ");
s.append("nice to see you, ");
s.append("or not.");

কারণ এটি কেবল একটি লাইনে একটি পাঠ্য যুক্ত করার তুলনায় জটিল।
— হাই-এঞ্জেল

11
s.append("One"); s.append(" line");
— জনি

16
@ জনি s.append("One").append(" expression");সম্ভবত ফিরতি মানটি এভাবে ব্যবহার করার জন্য আমার আসলটি সম্পাদনা করা উচিত?
— এপোনামস

5
@ সিলভারমুলস ওপি sসমতুল্য সি # কোড এবং তার নন-সংকলন সি ++ কোডে একটি ভিন্ন লাইনে ঘোষণা করে। তাঁর পছন্দসই সি ++ s += "Hello world, " + "nice to see you, " + "or not.";যা লেখা যেতে পারেs.append("Hello world, ").append("nice to see you, ").append("or not.");
— এপোনামস

4
এর একটি বড় সুবিধা appendহ'ল এটিতেও কাজ করা হয় যখন স্ট্রিংগুলিতে NUL টি অক্ষর থাকে।
— জন এস

62
s += "Hello world, " + "nice to see you, " + "or not.";

এই চরিত্রের অ্যারে আক্ষরিকাগুলি C ++ std :: স্ট্রিং নয় - আপনাকে সেগুলি রূপান্তর করতে হবে:

s += string("Hello world, ") + string("nice to see you, ") + string("or not.");

ইনটগুলিতে রূপান্তর করতে (বা অন্য কোনও স্ট্রাইমেবল টাইপ) আপনি একটি বস্ট লেজিকাল_কাস্ট ব্যবহার করতে পারেন বা আপনার নিজস্ব ফাংশন সরবরাহ করতে পারেন:

template <typename T>
string Str( const T & t ) {
   ostringstream os;
   os << t;
   return os.str();
}

আপনি এখন এ জাতীয় কথা বলতে পারেন:

string s = string("The meaning is ") + Str( 42 );

16
আপনাকে কেবল প্রথমটিকে স্পষ্টভাবে রূপান্তর করতে হবে: s + = স্ট্রিং ("হ্যালো ওয়ার্ল্ড,") + "আপনাকে দেখে ভাল লাগল," + "না" ";
— ফের্রুসিও

8
হ্যাঁ, তবে কেন আমি তা বোঝাতে পারিনি!

1
বুস্ট :: লেক্সিক্যাল_কাস্ট - আপনার স্টার ফাংশনে দুর্দান্ত এবং অনুরূপ :)
— বায়দা

2
কনস্ট্রাক্টরের ডানদিকে করা কনকনেটেশনগুলি ক্লাসে সংজ্ঞায়িত হয়ে string("Hello world")সম্পাদিত হয় । যদি অভিব্যক্তিটিতে কোনও অবজেক্ট না থাকে, তবে সম্মিলনটি কেবল চর পয়েন্টারের সমষ্টি হয়ে যায় । operator+()stringstringchar*
— ডেভাইড

41

আপনার কোড 1 হিসাবে লেখা যেতে পারে ,

s = "Hello world," "nice to see you," "or not."

... তবে আমি সন্দেহ করছি যে আপনি যা খুঁজছেন তা। আপনার ক্ষেত্রে, আপনি সম্ভবত স্ট্রিমগুলি সন্ধান করছেন:

std::stringstream ss;
ss << "Hello world, " << 42 << "nice to see you.";
std::string s = ss.str();

1 " হিসাবে লেখা যেতে পারে ": এটি কেবল স্ট্রিং লিটারেলের জন্য কাজ করে। সংমিশ্রণটি সংকলক দ্বারা সম্পন্ন হয়।


11
আপনার 1 ম উদাহরণটি উল্লেখ করার মতো, তবে দয়া করে এটি উল্লেখ করুন যে এটি কেবল "কনটেন্টেটিং" আক্ষরিক স্ট্রিংগুলির জন্য কাজ করে (সংকলক নিজেই কনটেন্টেশনটি সম্পাদন করে)।
— j_random_hacker

প্রথম উদাহরণটি আমার জন্য ত্রুটি ঘটিয়েছিল যদি কোনও স্ট্রিং আগে যেমন ঘোষণা করা হয়েছিল const char smthg[] = "smthg": / এটি কোনও বাগ?
— হাই-এঞ্জেল

@ হাই-অ্যাঞ্জেল দুর্ভাগ্যক্রমে নয়, পরিবর্তে, আপনি #defineআপনার স্ট্রিংটি এটিকে ঘিরে ধরতে পারেন , যদিও এটি তার নিজস্ব সমস্যা নিয়ে আসে।
— সিজেড

27

সি ++ 14 ব্যবহারকারীর সংজ্ঞায়িত আক্ষরিক এবং std::to_stringকোড ব্যবহার করা সহজ হয়ে যায়।

using namespace std::literals::string_literals;
std::string str;
str += "Hello World, "s + "nice to see you, "s + "or not"s;
str += "Hello World, "s + std::to_string(my_int) + other_string;

নোট করুন যে সংলগ্ন স্ট্রিং লিটারালগুলি সংকলন সময়ে করা যেতে পারে। শুধু অপসারণ +।

str += "Hello World, " "nice to see you, " "or not";

2
যেহেতু সি ++ 11 আপনি স্ট্যান্ড :: টু স্ট্রিং ব্যবহার করতে পারেন
— প্যাট্রিসিও রসি

ব্যবহারকারী সি ++ 11 <> থেকে আক্ষরিক সংজ্ঞায়িতও করেছেন । আমি সম্পাদনা করেছি।
— ড্যানি স্ট্যাক

@ স্ট্যাকড্যানি পরিবর্তনটি ভুল। যখন আমি "সি ++ ১৪" বলি আমি std::literals::string_literalsকোনও ইউডিএল ধারণাটি নয়, উল্লেখ করি ।
— Rapptz

16

আরও এক-লাইন ইশ concatএমন একটি সমাধান দেওয়ার জন্য: একটি বিবৃতিতে "ক্লাসিক" স্ট্রিংস্ট্রিম ভিত্তিক সমাধানকে হ্রাস করতে একটি ফাংশন প্রয়োগ করা যেতে পারে । এটি বৈকল্পিক টেম্পলেট এবং নিখুঁত ফরওয়ার্ডিংয়ের উপর ভিত্তি করে।


ব্যবহার:

std::string s = concat(someObject, " Hello, ", 42, " I concatenate", anyStreamableType);

বাস্তবায়ন:

void addToStream(std::ostringstream&)
{
}

template<typename T, typename... Args>
void addToStream(std::ostringstream& a_stream, T&& a_value, Args&&... a_args)
{
    a_stream << std::forward<T>(a_value);
    addToStream(a_stream, std::forward<Args>(a_args)...);
}

template<typename... Args>
std::string concat(Args&&... a_args)
{
    std::ostringstream s;
    addToStream(s, std::forward<Args>(a_args)...);
    return s.str();
}

বৃহত্তর কোড বেসে কম্বিনেশনের বিভিন্ন রকম থাকলে এটি কি সংকলনের সময় ফুলে উঠবে না?
— শীতল শাহ

1
@ শীতলশাহ কেবল সেই জিনিসগুলি ম্যানুয়ালি ইনলাইন লেখার চেয়ে বেশি কিছু নয়, যেহেতু এই সহায়ক সহায়কগুলি যেভাবেই কেবল ইনলাইন করা হবে।
— আন্ডারস্কোর_ডি

13

সি ++ তে আপনি করতে সক্ষম হবেন:

auto s = std::format("{}{}{}", "Hello world, ", myInt, niceToSeeYouString);

ততক্ষণ আপনি {fmt} লাইব্রেরির সাথে একই কাজ করতে পারবেন :

auto s = fmt::format("{}{}{}", "Hello world, ", myInt, niceToSeeYouString);

দাবি অস্বীকার: আমি {fmt of এর লেখক}


7

বুস্ট :: বিন্যাস

বা স্টাড :: স্ট্রিংস্ট্রিম

std::stringstream msg;
msg << "Hello world, " << myInt  << niceToSeeYouString;
msg.str(); // returns std::string object

6

প্রকৃত সমস্যা যে স্ট্রিং লিটারেল concatenating সঙ্গে ছিল +C ++ ব্যর্থ হলে:

string s;
s += "Hello world, " + "nice to see you, " + "or not.";
উপরের কোডটি একটি ত্রুটি তৈরি করে।

সি ++ তে (সি তেও), আপনি স্ট্রিং লিটারেলগুলিকে একে অপরের ঠিক ঠিক পাশে রেখে সংযুক্ত করেন:

string s0 = "Hello world, " "nice to see you, " "or not.";
string s1 = "Hello world, " /*same*/ "nice to see you, " /*result*/ "or not.";
string s2 = 
    "Hello world, " /*line breaks in source code as well as*/ 
    "nice to see you, " /*comments don't matter*/ 
    "or not.";

আপনি ম্যাক্রোগুলিতে কোড উত্পন্ন করলে এটি বোঝা যায়:

#define TRACE(arg) cout << #arg ":" << (arg) << endl;

... একটি সাধারণ ম্যাক্রো যা এইরকম ব্যবহার করা যেতে পারে

int a = 5;
TRACE(a)
a += 7;
TRACE(a)
TRACE(a+7)
TRACE(17*11)

( লাইভ ডেমো ... )

অথবা, যদি আপনি +স্ট্রিং লিটারালগুলির জন্য স্ট্র্যান্ড ব্যবহার করার জন্য জোর দিয়ে থাকেন (যেমন ইতিমধ্যে আন্ডারস্কোর_ডি দ্বারা পরামর্শ দেওয়া হয়েছে ):

string s = string("Hello world, ")+"nice to see you, "+"or not.";

আরেকটি সমাধান const char*প্রতিটি সংলগ্ন পদক্ষেপের জন্য একটি স্ট্রিং এবং একটি সংযুক্ত করে

string s;
s += "Hello world, "
s += "nice to see you, "
s += "or not.";

আমি এই কৌশলটিও প্রচুর ব্যবহার করি, তবে যদি এক বা একাধিক ভেরিয়েবলগুলি ইন / স্ট্রিং হয় তবে কী হবে? .eg string s = "abc" "Def" (int) y "ghi" (std :: શબ્દ) z "1234"; তারপরে, স্প্রিন্টফ এখনও আরও খারাপ সমাধানগুলির মধ্যে সেরা।
— বার্ট মেনসফর্ট

@ বার্টমেনসফোর্ট অবশ্যই sprintfএকটি বিকল্প, তবে এখানে স্ট্যান্ড স্ট্রিমস্ট্রিম রয়েছে যা আন্ডারাইজড বাফারগুলির সাথে সমস্যাগুলি প্রতিরোধ করে।
— ওল্ফ


3

স্ট্রিংটিতে কনসেন্ট করতে চান এমন প্রতিটি ডেটা টাইপের জন্য আপনাকে অপারেটর + () সংজ্ঞায়িত করতে হবে, তবুও অপারেটর << বেশিরভাগ ধরণের জন্য সংজ্ঞায়িত করা হয়েছে, আপনার স্টাডি :: স্ট্রিংস্ট্রিম ব্যবহার করা উচিত।

অভিশাপ, 50 সেকেন্ড দ্বারা পরাজিত ...


1
চর এবং ইন্টের মতো অন্তর্নির্মিত ধরনেরগুলিতে আপনি নতুন অপারেটরগুলি সংজ্ঞায়িত করতে পারবেন না।
— টাইলার ম্যাকহেনারি

1
@ টাইলারএমসি হেনরি এমন নয় যে আমি এই ক্ষেত্রে এটির প্রস্তাব দিই, তবে আপনি অবশ্যই করতে পারেন:std::string operator+(std::string s, int i){ return s+std::to_string(i); }
— নামবিহীন

3

আপনি যদি এটি লিখে রাখেন তবে +=এটি দেখতে প্রায় সি # এর মতোই

string s("Some initial data. "); int i = 5;
s = s + "Hello world, " + "nice to see you, " + to_string(i) + "\n";

3

অন্যরা যেমন বলেছিল, ওপি কোডের সাথে প্রধান সমস্যাটি হ'ল অপারেটর + সম্মিলিত হয় না const char *; std::stringযদিও এটি সাথে কাজ করে ।

এখানে আরও একটি সমাধান যা সি ++ 11 ল্যাম্বডাস ব্যবহার করে for_eachএবং এটি সরবরাহ করার অনুমতি দেয়separator স্ট্রিংগুলি পৃথক করার জন্য করতে :

#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>

string join(const string& separator,
            const vector<string>& strings)
{
    if (strings.empty())
        return "";

    if (strings.size() == 1)
        return strings[0];

    stringstream ss;
    ss << strings[0];

    auto aggregate = [&ss, &separator](const string& s) { ss << separator << s; };
    for_each(begin(strings) + 1, end(strings), aggregate);

    return ss.str();
}

ব্যবহার:

std::vector<std::string> strings { "a", "b", "c" };
std::string joinedStrings = join(", ", strings);

এটি কমপক্ষে আমার কম্পিউটারে একটি দ্রুত পরীক্ষার পরে, ভাল স্ক্রিন (রৈখিক) বলে মনে হচ্ছে; আমি লিখেছি একটি দ্রুত পরীক্ষা এখানে:

#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <chrono>

using namespace std;

string join(const string& separator,
            const vector<string>& strings)
{
    if (strings.empty())
        return "";

    if (strings.size() == 1)
        return strings[0];

    stringstream ss;
    ss << strings[0];

    auto aggregate = [&ss, &separator](const string& s) { ss << separator << s; };
    for_each(begin(strings) + 1, end(strings), aggregate);

    return ss.str();
}

int main()
{
    const int reps = 1000;
    const string sep = ", ";
    auto generator = [](){return "abcde";};

    vector<string> strings10(10);
    generate(begin(strings10), end(strings10), generator);

    vector<string> strings100(100);
    generate(begin(strings100), end(strings100), generator);

    vector<string> strings1000(1000);
    generate(begin(strings1000), end(strings1000), generator);

    vector<string> strings10000(10000);
    generate(begin(strings10000), end(strings10000), generator);

    auto t1 = chrono::system_clock::now();
    for(int i = 0; i<reps; ++i)
    {
        join(sep, strings10);
    }

    auto t2 = chrono::system_clock::now();
    for(int i = 0; i<reps; ++i)
    {
        join(sep, strings100);
    }

    auto t3 = chrono::system_clock::now();
    for(int i = 0; i<reps; ++i)
    {
        join(sep, strings1000);
    }

    auto t4 = chrono::system_clock::now();
    for(int i = 0; i<reps; ++i)
    {
        join(sep, strings10000);
    }

    auto t5 = chrono::system_clock::now();

    auto d1 = chrono::duration_cast<chrono::milliseconds>(t2 - t1);
    auto d2 = chrono::duration_cast<chrono::milliseconds>(t3 - t2);
    auto d3 = chrono::duration_cast<chrono::milliseconds>(t4 - t3);
    auto d4 = chrono::duration_cast<chrono::milliseconds>(t5 - t4);

    cout << "join(10)   : " << d1.count() << endl;
    cout << "join(100)  : " << d2.count() << endl;
    cout << "join(1000) : " << d3.count() << endl;
    cout << "join(10000): " << d4.count() << endl;
}

ফলাফল (মিলিসেকেন্ড):

join(10)   : 2
join(100)  : 10
join(1000) : 91
join(10000): 898

3

এটি সত্যিই এক লাইনে করার জন্য আপনি আমার "স্ট্রেমার" সমাধানটি পছন্দ করতে পারেন:

#include <iostream>
#include <sstream>
using namespace std;

class Streamer // class for one line string generation
{
public:

    Streamer& clear() // clear content
    {
        ss.str(""); // set to empty string
        ss.clear(); // clear error flags
        return *this;
    }

    template <typename T>
    friend Streamer& operator<<(Streamer& streamer,T str); // add to streamer

    string str() // get current string
    { return ss.str();}

private:
    stringstream ss;
};

template <typename T>
Streamer& operator<<(Streamer& streamer,T str)
{ streamer.ss<<str;return streamer;}

Streamer streamer; // make this a global variable


class MyTestClass // just a test class
{
public:
    MyTestClass() : data(0.12345){}
    friend ostream& operator<<(ostream& os,const MyTestClass& myClass);
private:
    double data;
};

ostream& operator<<(ostream& os,const MyTestClass& myClass) // print test class
{ return os<<myClass.data;}


int main()
{
    int i=0;
    string s1=(streamer.clear()<<"foo"<<"bar"<<"test").str();                      // test strings
    string s2=(streamer.clear()<<"i:"<<i++<<" "<<i++<<" "<<i++<<" "<<0.666).str(); // test numbers
    string s3=(streamer.clear()<<"test class:"<<MyTestClass()).str();              // test with test class
    cout<<"s1: '"<<s1<<"'"<<endl;
    cout<<"s2: '"<<s2<<"'"<<endl;
    cout<<"s3: '"<<s3<<"'"<<endl;
}

2

এখানে ওয়ান-লাইনারের সমাধান:

#include <iostream>
#include <string>

int main() {
  std::string s = std::string("Hi") + " there" + " friends";
  std::cout << s << std::endl;

  std::string r = std::string("Magic number: ") + std::to_string(13) + "!";
  std::cout << r << std::endl;

  return 0;
}

যদিও এটি একটি সামান্য বিরাট কুৎসিত, আমি মনে করি এটি আপনার বিড়াল সি ++ তে যেমন পরিচ্ছন্ন থাকে তেমন পরিষ্কার।

আমরা একটি প্রথম যুক্তি কাস্ট std::stringএবং তারপর (বাম থেকে ডানে) মূল্যায়ন অর্ডার ব্যবহার operator+তা নিশ্চিত করার জন্য তার বাম প্রতীক সবসময় একটি হল std::string। এই পদ্ধতিতে, আমরা ডানদিকে অপারেন্ড std::stringদিয়ে বামদিকে সংযুক্ত করি const char *এবং অন্যটিতে ফিরে আসিstd::string আসি, প্রভাবটি ক্যাসকেড করে।

নোট: সেখানে ডান প্রতীক জন্য কিছু বিকল্প সহ হয় const char *, std::stringএবংchar ।

ম্যাজিক নম্বরটি 13 বা 6227020800 কিনা তা সিদ্ধান্ত নেওয়া আপনার পক্ষে।


আহ, আপনি ভুলে গেছেন, @ অ্যাপলিগুলি, সর্বজনীন যাদু সংখ্যা 42 টি: ডি
— মিঃ জিউস


1

আপনি যদি ব্যবহার c++11করতে ইচ্ছুক হন তবে আপনি ব্যবহারকারী-সংজ্ঞায়িত স্ট্রিং আক্ষরিক ব্যবহার করতে পারেন এবং দুটি ফাংশন টেম্পলেট সংজ্ঞায়িত করতে পারেন যা কোনও std::stringবস্তু এবং অন্য কোনও বস্তুর জন্য প্লাস অপারেটরকে ওভারলোড করে । একমাত্র সমস্যাটি হ'ল প্লাস অপারেটরগুলির ওভারলোড না করা std::string, অন্যথায় সংকলকটি কোন অপারেটরটি ব্যবহার করবে তা জানে না। আপনি টেমপ্লেটটি ব্যবহার করে এটা করতে পারেন std::enable_ifথেকে type_traits। এর পরে স্ট্রিংগুলি জাভা বা সি # এর মতোই আচরণ করে। বিশদ জন্য আমার উদাহরণ বাস্তবায়ন দেখুন।

প্রধান কোড

#include <iostream>
#include "c_sharp_strings.hpp"

using namespace std;

int main()
{
    int i = 0;
    float f = 0.4;
    double d = 1.3e-2;
    string s;
    s += "Hello world, "_ + "nice to see you. "_ + i
            + " "_ + 47 + " "_ + f + ',' + d;
    cout << s << endl;
    return 0;
}

ফাইল c_sharp_strings.hpp

আপনি যেখানে এই স্ট্রিংগুলি রাখতে চান সেখানে এই হেডার ফাইলটি অন্তর্ভুক্ত করুন।

#ifndef C_SHARP_STRING_H_INCLUDED
#define C_SHARP_STRING_H_INCLUDED

#include <type_traits>
#include <string>

inline std::string operator "" _(const char a[], long unsigned int i)
{
    return std::string(a);
}

template<typename T> inline
typename std::enable_if<!std::is_same<std::string, T>::value &&
                        !std::is_same<char, T>::value &&
                        !std::is_same<const char*, T>::value, std::string>::type
operator+ (std::string s, T i)
{
    return s + std::to_string(i);
}

template<typename T> inline
typename std::enable_if<!std::is_same<std::string, T>::value &&
                        !std::is_same<char, T>::value &&
                        !std::is_same<const char*, T>::value, std::string>::type
operator+ (T i, std::string s)
{
    return std::to_string(i) + s;
}

#endif // C_SHARP_STRING_H_INCLUDED

1

এরকম কিছু আমার জন্য কাজ করে

namespace detail {
    void concat_impl(std::ostream&) { /* do nothing */ }

    template<typename T, typename ...Args>
    void concat_impl(std::ostream& os, const T& t, Args&&... args)
    {
        os << t;
        concat_impl(os, std::forward<Args>(args)...);
    }
} /* namespace detail */

template<typename ...Args>
std::string concat(Args&&... args)
{
    std::ostringstream os;
    detail::concat_impl(os, std::forward<Args>(args)...);
    return os.str();
}
// ...
std::string s{"Hello World, "};
s = concat(s, myInt, niceToSeeYouString, myChar, myFoo);

1

উপরের সমাধানগুলির উপর ভিত্তি করে আমি আমার প্রকল্পকে জীবন সহজ করার জন্য একটি শ্রেণি ভার_ স্ট্রিং তৈরি করেছি। উদাহরণ:

var_string x("abc %d %s", 123, "def");
std::string y = (std::string)x;
const char *z = x.c_str();

ক্লাস নিজেই:

#include <stdlib.h>
#include <stdarg.h>

class var_string
{
public:
    var_string(const char *cmd, ...)
    {
        va_list args;
        va_start(args, cmd);
        vsnprintf(buffer, sizeof(buffer) - 1, cmd, args);
    }

    ~var_string() {}

    operator std::string()
    {
        return std::string(buffer);
    }

    operator char*()
    {
        return buffer;
    }

    const char *c_str()
    {
        return buffer;
    }

    int system()
    {
        return ::system(buffer);
    }
private:
    char buffer[4096];
};

এখনও ভাবছেন যে সি ++ তে আরও ভাল কিছু হবে?


1

সি 11 এ:

void printMessage(std::string&& message) {
    std::cout << message << std::endl;
    return message;
}

এটি আপনাকে এই জাতীয় ফাংশন কল তৈরি করতে দেয়:

printMessage("message number : " + std::to_string(id));

মুদ্রণ করবে: বার্তা নম্বর: 10


0

আপনি স্ট্রিং ক্লাসটি "প্রসারিত" করতে এবং আপনি যে অপারেটরটি পছন্দ করেন তা চয়ন করতে পারেন (<<, &, |, ইত্যাদি ...)

স্টিমগুলির সাথে কোনও বিরোধ নেই তা দেখানোর জন্য অপারেটর <<< ব্যবহার করে কোডটি এখানে

দ্রষ্টব্য: যদি আপনি s1.re সংরক্ষণ (30) কে অবসন্ন করেন তবে কেবলমাত্র 3 টি নতুন () অপারেটর অনুরোধ রয়েছে (এস 1 এর জন্য 1, এস 2 এর জন্য 1, 1 রিজার্ভের জন্য; দুর্ভাগ্যক্রমে আপনি নির্মাতার সময়ে রিজার্ভ করতে পারবেন না); রিজার্ভ ছাড়াই, এস 1-এর বাড়ার সাথে সাথে আরও মেমোরির জন্য অনুরোধ করতে হবে, সুতরাং এটি আপনার সংকলক বাস্তবায়নের বৃদ্ধির ফ্যাক্টরের উপর নির্ভর করে (আমার এই উদাহরণে 1.5, 5 টি নতুন () কল রয়েছে)

namespace perso {
class string:public std::string {
public:
    string(): std::string(){}

    template<typename T>
    string(const T v): std::string(v) {}

    template<typename T>
    string& operator<<(const T s){
        *this+=s;
        return *this;
    }
};
}

using namespace std;

int main()
{
    using string = perso::string;
    string s1, s2="she";
    //s1.reserve(30);
    s1 << "no " << "sunshine when " << s2 << '\'' << 's' << " gone";
    cout << "Aint't "<< s1 << " ..." <<  endl;

    return 0;
}

0

ল্যাম্বডা ফাংশনটি ব্যবহার করে একটি সাধারণ প্রিপક્રোসেসর ম্যাক্রো সহ স্ট্রিংস্ট্রিমটি দুর্দান্ত দেখাচ্ছে:

#include <sstream>
#define make_string(args) []{std::stringstream ss; ss << args; return ss;}() 

এবং তারপর

auto str = make_string("hello" << " there" << 10 << '$');

-1

এটি আমার পক্ষে কাজ করে:

#include <iostream>

using namespace std;

#define CONCAT2(a,b)     string(a)+string(b)
#define CONCAT3(a,b,c)   string(a)+string(b)+string(c)
#define CONCAT4(a,b,c,d) string(a)+string(b)+string(c)+string(d)

#define HOMEDIR "c:\\example"

int main()
{

    const char* filename = "myfile";

    string path = CONCAT4(HOMEDIR,"\\",filename,".txt");

    cout << path;
    return 0;
}

আউটপুট:

c:\example\myfile.txt

12
একটি বিড়ালছানা প্রত্যেকবারই কোড গার্ড বা কনস্ট্যান্টের চেয়ে আরও জটিল কিছু জন্য ম্যাক্রোগুলি ব্যবহার করার সময় চিৎকার করে: পি
— রুই মার্কস

1
অসুখী বিড়ালছানাগুলির পাশাপাশি: প্রতিটি যুক্তির জন্য একটি স্ট্রিং অবজেক্ট তৈরি করা হয় যা প্রয়োজনীয় নয়।
— সেবাস্তিয়ানক

2
ডাউনভোটেড, যেহেতু ম্যাক্রোগুলি ব্যবহার করা অবশ্যই একটি খারাপ সমাধান
— ধৈমান

এটি এমনকি সি পর্যন্ত আমাকে ভয়াবহ করে তুলবে, তবে সি ++ এ এটি ডায়াবোলিকাল। @ রুইমার্কস: কোন পরিস্থিতিতে স্থিরদের জন্য ম্যাক্রোগুলি ভাল const(বা শূন্য স্টোরেজ প্রয়োজন হলে) enumহতে পারে?
— আন্ডারস্কোর_১

@ আসরস্কোর_ড আকর্ষণীয় প্রশ্ন তবে এর উত্তর আমার কাছে নেই। সম্ভবত উত্তর কিছুই না।
— রুই মার্কস

-1

আপনি কি + = এড়াতে চেষ্টা করেছেন? পরিবর্তে var = var + ব্যবহার করুন ... এটি আমার পক্ষে কাজ করে।

#include <iostream.h> // for string

string myName = "";
int _age = 30;
myName = myName + "Vincent" + "Thorpe" + 30 + " " + 2019;

আমি সি ++ বোরল্যান্ড বিল্ডার 6 ব্যবহার করি এবং এটি আমার পক্ষে ভাল কাজ করে। এই শিরোলেখগুলি অন্তর্ভুক্ত করতে ভুলবেন না#include <iostream.h> // string #include <system.hpp> // ansiString
— ভিনসেন্ট থর্প

+ = এই ক্ষেত্রে অত্যধিক বোঝা নয়, মনে হয় যে আপনি সংখ্যা যুক্ত করেছেন এবং
— কংক্রিটেট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.