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


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.