मैं एक लाइन पर कई C ++ स्ट्रिंग्स को कैसे समाहित कर सकता हूं?


150

C # में एक सिंटैक्स सुविधा है जहां आप 1 लाइन पर कई डेटा प्रकारों को एक साथ जोड़ सकते हैं।

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

C ++ में क्या बराबर होगा? जहाँ तक मैं देख सकता हूँ, आपको यह सब अलग-अलग लाइनों पर करना होगा क्योंकि यह + ऑपरेटर के साथ कई स्ट्रिंग्स / वेरिएबल्स का समर्थन नहीं करता है। यह ठीक है, लेकिन उतना साफ नहीं है।

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 << "वाह, सी + + में स्ट्रिंग संघनन प्रभावशाली है" << "या नहीं।"
जोआर्ल

4
बस दूसरे तरीके से नाम रखने के लिए: कई एपेंड का उपयोग करते हुए: स्ट्रिंग एस = स्ट्रिंग ("एबीसी")।
पैट्रिकियो रॉसी

1
std::stringstream ss; ss << "Hello, world, " << myInt << niceToSeeYouString; std::string s = ss.str();बहुत ज्यादा एक-पंक्ति है
Kotauskas

74

5 साल में किसी ने जिक्र नहीं किया .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");शायद मुझे इस तरह से वापसी मूल्य का उपयोग करने के लिए मूल को संपादित करना चाहिए?
16

5
@ सिल्वरमॉल्स ओपी sबराबर सी # कोड में एक अलग लाइन पर और अपने गैर-संकलन सी ++ कोड में घोषित करता है । उनका वांछित C ++ 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 :: strings नहीं हैं - आपको उन्हें बदलने की आवश्यकता है:

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

Ints (या किसी अन्य स्ट्रीम करने योग्य प्रकार) को बदलने के लिए आप एक बूस्ट lexical_cast का उपयोग कर सकते हैं या अपना स्वयं का फ़ंक्शन प्रदान कर सकते हैं:

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 + = string ("हेल्लो वर्ल्ड,") + "आपको देखकर अच्छा लगा," + "या नहीं";
फेरुशियो

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
आपका पहला उदाहरण ध्यान देने योग्य है, लेकिन यह भी उल्लेख करें कि यह केवल "कंक्रीटिंग" के लिए काम करता है शाब्दिक तार (कंपाइलर कॉन्टेक्टेशन स्वयं करता है)।
j_random_hacker

पहला उदाहरण मेरे लिए एक त्रुटि पैदा करता है अगर एक स्ट्रिंग पहले से घोषित किया गया था जैसे const char smthg[] = "smthg": / क्या यह एक बग है?
हाय-एंजेल

@ हाय-एंजेल दुर्भाग्य से, इसके बजाय, आप इसे #defineप्राप्त करने के लिए अपनी स्ट्रिंग कर सकते हैं , हालांकि यह अपनी समस्याएं लाता है।
cz

27

C ++ 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
C ++ 11 के बाद से आप std :: to_string
Patricio Rossi

C ++ 11 <> के बाद से उपयोगकर्ता परिभाषित शाब्दिक भी । मैंने संपादित किया।
स्टैक डैनी

@StackDanny परिवर्तन गलत है। जब मैं कहता हूं "C ++ 14", तो मैं यूडीएल std::literals::string_literalsकी अवधारणा का उल्लेख करता हूं ।
रैपर्ट्ज

16

एक समाधान है कि और अधिक एक पंक्ति का-ish है की पेशकश करने के लिए: एक समारोह concat"क्लासिक" stringstream आधारित एक का हल कम करने के लिए लागू किया जा सकता एकल कथन । यह वैरेडिक टेम्प्लेट और परफेक्ट फॉरवर्डिंग पर आधारित है।


उपयोग:

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

C ++ 20 में आप कर पाएंगे:

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

तब तक आप {fmt} लाइब्रेरी के साथ भी ऐसा कर सकते हैं :

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

अस्वीकरण : मैं {fmt} का लेखक हूं।


7

बढ़ावा :: प्रारूप

या एसटीडी :: स्ट्रिंग

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

6

वास्तविक समस्या है कि स्ट्रिंग शाब्दिक श्रृंखलाबद्ध के साथ था +C ++ में विफल रहता है:

string s;
s += "Hello world, " + "nice to see you, " + "or not.";
उपरोक्त कोड एक त्रुटि पैदा करता है।

C ++ में (C में भी), आप स्ट्रिंग शाब्दिकों को केवल एक दूसरे के ठीक बगल में रखकर समतल करते हैं:

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.";

मैं भी इस तकनीक का बहुत उपयोग करता हूं, लेकिन क्या होगा अगर एक या अधिक चर int / string हो? .eg स्ट्रिंग s = "abc" "def" (int) y "ghi" (std :: string) z "1234"; फिर, स्प्रिंटफ अभी भी सबसे खराब समाधान है।
बार्ट मेन्सफोर्ट

@BartMensfort बेशक sprintfएक विकल्प है, लेकिन इसमें std :: stringstream भी है जो अंडरसिज्ड बफ़र्स के साथ समस्याओं को रोकता है।
वुल्फ


3

आपको प्रत्येक डेटा प्रकार के लिए ऑपरेटर + () को परिभाषित करना होगा, जिसे आप स्ट्रिंग में संक्षिप्त करना चाहते हैं, फिर भी चूंकि ऑपरेटर << को अधिकांश प्रकारों के लिए परिभाषित किया गया है, इसलिए आपको std :: stringstream का उपयोग करना चाहिए।

धिक्कार है, 50 सेकंड से हरा ...


1
आप वास्तव में नए प्रकारों को परिभाषित नहीं कर सकते जैसे बिल्ट-इन प्रकार जैसे चार और इंट।
टायलर मैकहेनरी

1
@TylerMcHenry नहीं कि मैं इस मामले में इसकी सिफारिश करूँगा, लेकिन आप निश्चित रूप से कर सकते हैं:std::string operator+(std::string s, int i){ return s+std::to_string(i); }
1937 '

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हालांकि, इसके साथ काम करता है ।

यहाँ एक और समाधान है जो C ++ 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।


आह, आप भूल जाते हैं, @Apollys, सार्वभौमिक जादू संख्या 42 है।: डी
श्रीज़्यूस


1

यदि आप उपयोग करने के लिए तैयार हैं तो आप उपयोगकर्ता द्वारा परिभाषित स्ट्रिंग शाब्दिकोंc++11 का उपयोग कर सकते हैं और दो फ़ंक्शन टेम्प्लेट परिभाषित कर सकते हैं जो std::stringकिसी ऑब्जेक्ट और किसी अन्य ऑब्जेक्ट के लिए प्लस ऑपरेटर को अधिभारित करते हैं । एकमात्र नुकसान प्लस ऑपरेटरों के अधिभार का नहीं है std::string, अन्यथा कंपाइलर को पता नहीं है कि किस ऑपरेटर का उपयोग करना है। आप टेम्पलेट का उपयोग कर ऐसा कर सकते हैं std::enable_ifसे type_traits। उसके बाद तार जावा या C # की तरह व्यवहार करते हैं। विवरण के लिए मेरा उदाहरण कार्यान्वयन देखें।

मुख्य कोड

#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 बनाया। उदाहरण:

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];
};

फिर भी सोच रहा था कि क्या C ++ में कुछ बेहतर होगा?


1

C11 में:

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

यह आपको फंक्शन कॉल बनाने की अनुमति देता है:

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

प्रिंट होगा: संदेश संख्या: 10


0

आप स्ट्रिंग क्लास का "विस्तार" भी कर सकते हैं और उस ऑपरेटर को चुन सकते हैं जिसे आप पसंद करते हैं (<<, &,।, आदि ...)

यहाँ ऑपरेटर का उपयोग करने वाला कोड है << यह दिखाने के लिए कि धाराओं के साथ कोई विरोध नहीं है

नोट: यदि आप s1.reserve (30) को अनकंफर्ट करते हैं, तो केवल 3 नए () ऑपरेटर अनुरोध (s1 के लिए 1, s2 के लिए 1, रिजर्व के लिए 1; आप कंस्ट्रक्टर के समय दुर्भाग्य से आरक्षित नहीं कर सकते हैं); रिजर्व के बिना, s1 को अधिक मेमोरी का अनुरोध करना पड़ता है क्योंकि यह बढ़ता है, इसलिए यह आपके संकलक कार्यान्वयन विकास कारक पर निर्भर करता है (मेरा लगता है कि इस उदाहरण में 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होगा?
अंडरस्कोर_

@underscore_d दिलचस्प सवाल है, लेकिन मेरे पास इसके लिए कोई जवाब नहीं है। शायद इसका जवाब कोई नहीं है।
रुई Marques

-1

क्या आपने + = से बचने की कोशिश की है? इसके बजाय var = var + का उपयोग करें ... यह मेरे लिए काम करता है।

#include <iostream.h> // for string

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

मैं C ++ बोरलैंड बिल्डर 6 का उपयोग करता हूं, और यह मेरे लिए ठीक काम करता है। इस हेडर#include <iostream.h> // string #include <system.hpp> // ansiString
विनसेंट थॉर्प

+ = इस मामले के लिए अतिभारित नहीं है, लगता है कि आप संख्याओं को जोड़ रहे थे और न कि
समवर्ती
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.