सी ++ मल्टीलाइन स्ट्रिंग शाब्दिक


415

क्या बहु-स्तरीय सादा-पाठ, C ++ में निरंतर शाब्दिक, ला ला पर्ल का कोई तरीका है? शायद #includeएक फ़ाइल के साथ कुछ पार्सिंग चाल ? मैं एक के बारे में सोच नहीं सकता, लेकिन लड़का, यह अच्छा होगा। मुझे पता है कि यह C ++ 0x में होगा।


1
आम तौर पर आप स्ट्रिंग लिटरल्स को कोड में एम्बेड नहीं करना चाहते हैं। I18N और L10N के लिए यह स्ट्रिंग कॉन्फ़िगरेशन को एक कॉन्फ़िगरेशन फ़ाइल में रखना बेहतर होता है जो रन टाइम पर लोड होती है।
मार्टिन

45
ऐसे पर्याप्त मामले हैं जहां स्ट्रिंग शाब्दिकों को कोड में डालना कोई समस्या नहीं है: यदि स्ट्रिंग का उपयोग उपयोगकर्ता को प्रस्तुत करने के लिए नहीं किया गया है; यानी: एसक्यूएल स्टेटमेंट्स, फाइल नेम, रजिस्ट्री की नेम, कमांड लाइन को निष्पादित करने के लिए ...
mmmmmmmm

2
@ मर्टिन: यह अभी भी जानना उपयोगी हो सकता है। मैंने इसे जटिल रीजैक्स को तोड़ने के लिए किया है, उदाहरण के लिए।
बोजूम

जवाबों:


591

अच्छी तरह की। सबसे आसान सिर्फ इस तथ्य का उपयोग करना है कि आसन्न स्ट्रिंग शाब्दिक संकलक द्वारा समेटे हुए हैं:

const char *text =
  "This text is pretty long, but will be "
  "concatenated into just a single string. "
  "The disadvantage is that you have to quote "
  "each part, and newlines must be literal as "
  "usual.";

इंडेंटेशन मायने नहीं रखता, क्योंकि यह उद्धरण के अंदर नहीं है।

आप यह भी कर सकते हैं, जब तक आप एम्बेडेड न्यूलाइन से बचने के लिए ध्यान रखते हैं। ऐसा करने में विफलता, जैसे मेरा पहला उत्तर था, संकलन नहीं होगा:

const char * text2 =
  "यहाँ, दूसरी ओर, मैं पागल हो गया हूँ"
और वास्तव में शाब्दिक कई पंक्तियों को फैलाया, \
प्रत्येक पंक्ति के उद्धरण से परेशान हुए बिना
सामग्री। यह काम करता है, लेकिन आप इंडेंट नहीं कर सकते हैं। "

फिर से, प्रत्येक पंक्ति के अंत में उन बैकस्लैश पर ध्यान दें, लाइन समाप्त होने से पहले उन्हें तुरंत होना चाहिए, वे स्रोत में नई रेखा से बच रहे हैं, ताकि सब कुछ ऐसा हो जाए जैसे कि नई रेखा नहीं थी। आपको उन स्थानों पर स्ट्रिंग में नए समाचार नहीं मिलते हैं, जहां आपके पास बैकस्लैश थे। इस फॉर्म के साथ, आप स्पष्ट रूप से पाठ को इंडेंट नहीं कर सकते क्योंकि इंडेंटेशन फिर स्ट्रिंग का हिस्सा बन जाएगा, इसे यादृच्छिक रिक्त स्थान के साथ जोड़कर।


3
मुझे अतीत में बताया गया है कि पहला विकल्प कार्यान्वयन तक हो सकता है, हालांकि मुझे अभी तक एक संकलक ढूंढना है जो उस वाक्यविन्यास का सम्मान नहीं करता है।
जेसन मॉक

28
@ जेसन: यह पूर्व-C89 संकलक का एक हिस्सा नहीं था, लेकिन यह C89 में परिभाषित किया गया है और इसलिए हर जगह अनिवार्य रूप से समर्थित है।
जोनाथन लेफ़लर

4
इसके अलावा, यदि आप वास्तव में चाहते हैं कि स्ट्रिंग को c ++ 98 में कई लाइनों पर स्वरूपित किया जाए तो प्रत्येक उद्धृत स्ट्रिंग टुकड़े पर स्थान खाली करने के लिए बस स्थानापन्न \ n। C ++ 11 कच्चे लीटर अभी भी मेरे पसंदीदा हैं।
ईम्र

3
@unwind नोट करें कि सोर्स लाइन के अंत में नई लाइन को स्ट्रिंग का हिस्सा नहीं बनाया गया है, यह सिर्फ छोड़ दिया गया है। यदि आप स्ट्रिंग के भाग के रूप में एक नई रेखा चाहते हैं, तो आपको पंक्ति के अंत में \ n \ _ होना चाहिए।
हाइड

2
Microsoft Visual Studio में बुरा बग है। यदि आप लाइनों के अंत में बैकस्लैश का उपयोग करते हैं, तो यह स्वचालित रूप से स्ट्रिंग के अंदर पाठ को इंडेंट करता है।
पलोटा

406

C ++ 11 में आपके पास कच्चे स्ट्रिंग शाब्दिक हैं। यहाँ छाँटे-छाँटे जैसे पाठ और पायथन और पर्ल और रूबी जैसी लिपि भाषाओं में।

const char * vogon_poem = R"V0G0N(
             O freddled gruntbuggly thy micturations are to me
                 As plured gabbleblochits on a lurgid bee.
              Groop, I implore thee my foonting turlingdromes.   
           And hooptiously drangle me with crinkly bindlewurdles,
Or I will rend thee in the gobberwarts with my blurlecruncheon, see if I don't.

                (by Prostetnic Vogon Jeltz; see p. 56/57)
)V0G0N";

सभी रिक्त स्थान और इंडेंटेशन और स्ट्रिंग में newlines संरक्षित हैं।

ये भी utf-8 | 16 | 32 या wchar_t (सामान्य उपसर्गों के साथ) हो सकते हैं।

मुझे कहना चाहिए कि भागने का क्रम, V0G0N, वास्तव में यहाँ की आवश्यकता नहीं है। इसकी उपस्थिति स्ट्रिंग के अंदर डालने की अनुमति देती है) "दूसरे शब्दों में, मैं डाल सकता था

                "(by Prostetnic Vogon Jeltz; see p. 56/57)"

(नोट अतिरिक्त उद्धरण) और उपरोक्त स्ट्रिंग अभी भी सही होगी। वरना मैं भी बस इस्तेमाल कर सकता था

const char * vogon_poem = R"( ... )";

उद्धरण के अंदर अभी भी parens की जरूरत है।


23
यह वास्तव में मैं क्या चाहता हूं, उद्धरणों से बचने की क्षमता, बैकस्लैश-एनएस, बच जाता है, और अभी भी वास्तविक स्ट्रिंग में नए समाचार दिखाई देते हैं। यह एम्बेडेड कोड (जैसे शेड्स या लुआ) के लिए आसान है। दुर्भाग्य से, हम अभी तक C ++ - 0x का उपयोग नहीं कर रहे हैं। :-(
mlepage

2
मैं खुद एम्बेडेड SQL और पायथन स्क्रिप्ट के लिए इस पर विचार कर रहा था। मैं आपकी खातिर उम्मीद कर रहा था कि शायद जीसीसी इसे सी ++ 98 मोड के माध्यम से स्लाइड करेगा लेकिन, अफसोस, नहीं।
Emsr

3
मुझे और घूरने की आदत है। इस संकलक में आपको C ++ 0x या c ++ 11 के लिए एक ध्वज सेट करना होगा। लुकिन एमएस वेबसाइट पर ऐसा लगता है कि उनके पास अभी तक कच्चे शाब्दिक नहीं हैं। मुझे समझ में आया कि MS नए कंपाइलर अपडेट को जल्दी से जारी करेगा क्योंकि C ++ फीचर्स लागू हो जाते हैं। विज़ुअल C ++ कंपाइलर नवंबर 2012 CTP [ microsoft.com/en-us/download/details.aspx?id=35515] को लेटेस्ट ब्लीडिंग एज के लिए देखें।
ईम्र्स

5
@rsethc कोड के ब्लॉक को कमेंट करने के लिए बस उपयोग करें #if 0... #endifघोंसले भी।
बोब्बोगो

1
वोगन कविता से प्रेरित!
ठाणे प्लमर

27

#define MULTILINE(...) #__VA_ARGS__
कोष्ठक के बीच सब कुछ का उपभोग करता है।
किसी एकल स्थान द्वारा किसी भी संख्या में लगातार व्हाट्सएप वर्णों को प्रतिस्थापित करता है।


1
आप जोड़ सकते हैं \nअगर आपको नई सुर्खियों की जरूरत है
साइमन

ध्यान दें कि ` (and hence \ n ) is copied literally, but "` को रूपांतरित किया जाता है \"। इसलिए MULTILINE(1, "2" \3)पैदावार "1, \"2\" \3"
एंड्रियास स्पिंडलर

@AndreasSpindler उद्धरण और बैकस्लैश एक जैसे (अतिरिक्त) बैकस्लैश से तब तक बचते हैं जब तक वे एक स्ट्रिंग या वर्ण शाब्दिक टोकन के अंदर दिखाई नहीं देते। निश्चित नहीं है कि आपकी बात क्या है एक बेजोड़ उद्धरण (डबल या सिंगल) रखना गैरकानूनी है, इसलिए संकुचन काम नहीं करते हैं, या उनमें से एक विषम संख्या वैसे भी होती है, जो शायद सबसे बड़ा नकारात्मक पक्ष है। वैसे भी +1। "रियल प्रोग्रामर" हमेशा जोड़े में संकुचन का उपयोग करते हैं, जिसमें कोई हस्तक्षेप करने वाली न्यूलाइन नहीं होती है ताकि एकल उद्धरण संतुलन हो।
पोटाटोस्वाटर

मुद्दा यह है कि उन्होंने लिखा "कोष्ठकों के बीच सब कुछ खा जाता है"।
एंड्रियास स्पिंडलर

25

मल्टी-लाइन स्ट्रिंग्स में प्रवेश करने का एक सुविधाजनक तरीका मैक्रो का उपयोग करके है। यह केवल तभी काम करता है जब उद्धरण और कोष्ठक संतुलित हों और इसमें 'शीर्ष स्तर' अल्पविराम शामिल न हो:

#define MULTI_LINE_STRING(a) #a
const char *text = MULTI_LINE_STRING(
  Using this trick(,) you don't need to use quotes.
  Though newlines and     multiple     white   spaces
  will be replaced by a single whitespace.
);
printf("[[%s]]\n",text);

Gcc 4.6 या g ++ 4.6 के साथ संकलित, यह उत्पादन करता है: [[Using this trick(,) you don't need to use quotes. Though newlines and multiple white spaces will be replaced by a single whitespace.]]

ध्यान दें कि ,यह स्ट्रिंग में नहीं हो सकता है, जब तक कि इसे कोष्ठक या उद्धरण के भीतर समाहित नहीं किया गया है। एकल उद्धरण संभव है, लेकिन संकलक चेतावनी बनाता है।

संपादित करें: जैसा कि टिप्पणियों में बताया गया है, #define MULTI_LINE_STRING(...) #__VA_ARGS__के उपयोग की अनुमति देता है ,


एक परियोजना के लिए जिसमें मैं कुछ ++ कोड स्निपेट को c ++ में शामिल करना चाहता था, मैंने एक छोटी सी पाइथन स्क्रिप्ट लिखना समाप्त कर दिया, जिसमें मैंने मल्टीलाइन स्ट्रिंग्स में प्रवेश किया, और उस सी + + स्रोत फ़ाइल को उत्पन्न किया।
bcmpinc

मेरे लिए बिल्कुल सही, इकाई परीक्षण के लिए कोलाडा फ़ाइल से एक विशाल बहु-रेखा फ्लोट-सूची स्ट्रिंग जोड़ना। मुझे हर जगह उद्धरण डालने की कल्पना नहीं थी, मुझे कॉपी और पेस्ट समाधान की आवश्यकता थी।
सोयालेंट ग्राहम

7
#define MULTILINE(...) #__VA_ARGS__यदि आप चाहते हैं कि आप अपने स्ट्रिंग को कॉमा में शामिल कर सकते हैं ।
साइमन

2
ध्यान दें कि यह सबसे अतिरिक्त whitesapce (सभी सहित नहीं हटेगा \nऔर \r), जो कुछ मामलों के लिए काम की तरह और दूसरों के लिए घातक है।
BCS

17

आप यह भी कर सकते हैं:

const char *longString = R""""(
This is 
a very 
long 
string
)"""";

2
धन्यवाद, यह महान है, सी में char longString[] = R""""( This is a very long string )""""; भी काम करता है, जाहिर है, मेरे लिए भी काम करता है।
संघर्षरत_लोनर

2
क्या यह एक नई लाइन के साथ स्ट्रिंग को शुरू और समाप्त करता है?
टिम एमबी

1
यह एक कच्चा स्ट्रिंग शाब्दिक है । C ++ 11 के बाद से उपलब्ध है।
मिकोलसन

15

आप ऐसा कर सकते हैं:

const char *text = "This is my string it is "
     "very long";

यह @ खोल के जवाब से कैसे अलग है?
शिशिर

1
@ शिशिर मैंने इसे 2 मिनट पहले पोस्ट किया।
एरिक

उस हिस्से को गायब करने के लिए क्षमा याचना। मेरा +1
शिशिर

10

चूंकि अनुभव का एक औंस सिद्धांत के एक टन के लायक है, मैंने इसके लिए थोड़ा परीक्षण कार्यक्रम की कोशिश की MULTILINE:

#define MULTILINE(...) #__VA_ARGS__

const char *mstr[] =
{
    MULTILINE(1, 2, 3),       // "1, 2, 3"
    MULTILINE(1,2,3),         // "1,2,3"
    MULTILINE(1 , 2 , 3),     // "1 , 2 , 3"
    MULTILINE( 1 , 2 , 3 ),   // "1 , 2 , 3"
    MULTILINE((1,  2,  3)),   // "(1,  2,  3)"
    MULTILINE(1
              2
              3),             // "1 2 3"
    MULTILINE(1\n2\n3\n),     // "1\n2\n3\n"
    MULTILINE(1\n
              2\n
              3\n),           // "1\n 2\n 3\n"
    MULTILINE(1, "2" \3)      // "1, \"2\" \3"
};

इस टुकड़े cpp -P -std=c++11 filenameको पुन: पेश करने के लिए संकलित करें ।

इसके पीछे की चाल #__VA_ARGS__यह है कि __VA_ARGS__अल्पविराम विभाजक को संसाधित नहीं करता है। तो आप इसे स्ट्रिंगिंग ऑपरेटर को पास कर सकते हैं। अग्रणी और अनुगामी रिक्त स्थान छंटनी की जाती हैं, और शब्दों के बीच रिक्त स्थान (नई-नई सहित) तब एक ही स्थान पर संकुचित होते हैं। कोष्ठक को संतुलित करने की आवश्यकता है। मुझे लगता है कि इन कमियों की वजह से C ++ 11 के डिजाइनरों #__VA_ARGS__ने कच्चे स्ट्रिंग शाब्दिकों की आवश्यकता को देखा।


9

सिर्फ @ खोल के जवाब में @ emsr की टिप्पणी पर थोड़ा सा विचार करें, यदि कोई भाग्यशाली नहीं है कि उसके पास C ++ 11 कंपाइलर (GCC 4.2.1 कहें), और कोई स्ट्रिंग में नईलाइन्स एम्बेड करना चाहता है (या तो char * या कक्षा स्ट्रिंग), कोई इस तरह से कुछ लिख सकता है:

const char *text =
  "This text is pretty long, but will be\n"
  "concatenated into just a single string.\n"
  "The disadvantage is that you have to quote\n"
  "each part, and newlines must be literal as\n"
  "usual.";

बहुत स्पष्ट, सत्य, लेकिन @ एम्सआर की संक्षिप्त टिप्पणी मेरे द्वारा पहली बार पढ़ने पर मेरे बारे में नहीं छपी थी, इसलिए मुझे इसके लिए स्वयं को खोजना पड़ा। उम्मीद है, मैंने कुछ मिनटों के बाद किसी और को बचाया है।


-1
// C++11. 
std::string index_html=R"html(
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>VIPSDK MONITOR</title>
    <meta http-equiv="refresh" content="10">
</head>
<style type="text/css">
</style>
</html>
)html";

कृपया अपने उत्तर में एक स्पष्टीकरण जोड़ें और न केवल कोड स्निपेट्स
जियोर्डी

-1

विकल्प 1. बूस्ट लाइब्रेरी का उपयोग करके, आप स्ट्रिंग को नीचे घोषित कर सकते हैं

const boost::string_view helpText = "This is very long help text.\n"
      "Also more text is here\n"
      "And here\n"

// Pass help text here
setHelpText(helpText);

विकल्प 2. यदि आपके प्रोजेक्ट में बूस्ट उपलब्ध नहीं है, तो आप आधुनिक C ++ में std :: string_view () का उपयोग कर सकते हैं।

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