कैसे एक एसटीडी :: एक एसटीडी से स्ट्रिंग :: वेक्टर <चार> का निर्माण करने के लिए?


115

लघु (स्पष्ट) सी शैली स्ट्रिंग का निर्माण पहले तो एक std :: string बनाने के लिए उपयोग करते हुए, क्या कोई वेक्टर के तार से एक स्ट्रिंग को इनिशियलाइज़ करने का एक तेज / वैकल्पिक / "बेहतर" तरीका है?


4
क्या यह नकल के बिना किया जा सकता है? दूसरे शब्दों जो कुछ के रूप में एक ही बात करता है में std::vector<char> v2(std::move(v)), लेकिन एक साथ std::stringनई वस्तु के रूप में।
tobi_s

जवाबों:


197

ठीक है, सबसे अच्छा तरीका निम्नलिखित निर्माता का उपयोग करना है:

template<class InputIterator> string (InputIterator begin, InputIterator end);

जिसके कारण कुछ ऐसा होगा:

std::vector<char> v;
std::string str(v.begin(), v.end());

41

मुझे लगता है कि आप बस कर सकते हैं

std::string s( MyVector.begin(), MyVector.end() );

जहाँ MyVector आपका std :: वेक्टर है।


1
VS2013 को छोड़कर जो अमान्य पुनरावृत्तियों के बारे में रनटाइम में दावा करता है, जब तक कि आप सेट नहीं करते हैं _ITERATOR_DEBUG_LEVEL=1(जिस स्थिति में यह ठीक काम करता है)।
कैमरन

35

C ++ 11 के साथ, आप कर सकते हैं std::string(v.data())या, यदि आपका वेक्टर '\0'अंत में नहीं है, तो std::string(v.data(), v.size())


C ++ 98 के साथ भी, मेरा मानना ​​है कि आप std :: string (& v [0]) कर सकते हैं। यह, ज़ाहिर है, अगर वेक्टर अशक्त है।
जेमी

1
@Jamie: वैसे, सी ++ 98 में, string(&v[0], v.size())भी काम करना चाहिए, लेकिन केवल के बाद assert(not v.empty());, क्योंकि अगर वेक्टर खाली है, दोनों v[0]और v.front()अपरिभाषित व्यवहार आह्वान करेंगे। कि, पता-संचालक का उपयोग न करने की वाक्यगत सादगी से अलग, C ++ 11 के data()फ़ंक्शन का वास्तविक लाभ है , जो एक खाली वेक्टर पर भी काम करता है।
एडम एच। पीटरसन

सच सच। दुर्भाग्य से, मेरी परियोजना दृश्य स्टूडियो 2008 पर भविष्य के भविष्य के लिए अटक गई है। सबसे पहले वेक्टर लंबाई की जाँच के बारे में।
जेमी

यदि वेक्टर में '\ 0' शामिल नहीं है, तो std::string(v.data())एक लंबी स्ट्रिंग हो सकती है। इसलिए इस तरह का उपयोग न करें।
heLomaN 12

@heLomaN: क्या गलत है std::string(v.data(), v.size()), जो स्पष्ट रूप से उस सटीक कारण के जवाब में उल्लेख किया गया था?
एस.जे.

12
std::string s(v.begin(), v.end());

जहां v बहुत अधिक चलने योग्य है। (विशेष रूप से शुरू () और अंत () InputIterators को वापस करना होगा।)


3

पूर्णता के लिए, एक और तरीका है std::string(&v[0])(हालांकि आपको यह सुनिश्चित करने की आवश्यकता है कि आपकी स्ट्रिंग शून्य से समाप्त हो गई है और std::string(v.data())आमतौर पर पसंद किया जाना है।

अंतर यह है कि आप वेक्टर को उन कार्यों को पास करने के लिए पूर्व तकनीक का उपयोग कर सकते हैं जो बफर को संशोधित करना चाहते हैं, जो आप .data () के साथ नहीं कर सकते हैं।


आप data()बफर को संशोधित करने के लिए उपयोग क्यों नहीं कर सकते हैं ? यह मुझे ऐसा लगता है कि यदि आप data()एक नॉन-कास्ट वेक्टर पर कॉल करते हैं, तो यह एक T *(और अगर आपका वेक्टर कांस्टेबल है, तो 'v [0] `किसी T const &भी तरह वापस आ जाएगा )।
एडम एच। पीटरसन

@ AdamH.Peterson यह मानक में एक निरीक्षण प्रतीत होता है। Std :: वेक्टर के डेटा में const और non-const दोनों प्रकार्य होते हैं, जबकि वर्तमान मानक में, std :: string में केवल एक const फ़ंक्शन होता है: en.cppreference.com/w/cpp/string/basic_string/data ध्यान दें कि ++ 17 एक गैर-कॉन्स्टेंस संस्करण जोड़ता है, इसलिए यह अनिश्चित काल तक नहीं हो सकता है - हालांकि, वर्तमान मानक कहते हैं "डेटा के माध्यम से एक्सेस किए गए वर्ण सरणी को संशोधित करना अपरिभाषित व्यवहार है।"
दंगा

यह सच होगा अगर vएक स्ट्रिंग थे, लेकिन लक्ष्य प्रकार एक स्ट्रिंग है और vएक वेक्टर है। (लेकिन यह देखना अच्छा है कि C ++ 17 वेक्टर के साथ तार समता देगा।)
एडम एच। पीटरसन

@ AdamH.Peterson आप बिल्कुल सही हैं। कुछ समय पहले इस सवाल का जवाब दिया गया था, मैंने मान लिया था कि यह पूरा सवाल बिना किसी जाँच के तार के बारे में था।
दंगा

2

मुझे स्टीफन का जवाब पसंद है (सितम्बर 11 '13) लेकिन इसे थोड़ा और मजबूत बनाना चाहूंगा:

यदि वेक्टर एक शून्य टर्मिनेटर के साथ समाप्त होता है, तो आपको C ++ 17 से पहले उन लोगों के लिए v.data () (या (या & V [0]) का उपयोग नहीं करना चाहिए (v.begin (), v.end ())। ।

यदि v में एक शून्य टर्मिनेटर नहीं है, तो आपको (v.begin (), v.end ()) का उपयोग करना चाहिए।

यदि आप शुरू () और अंत का उपयोग करते हैं () और वेक्टर में एक शून्य होता है, तो आप एक स्ट्रिंग "abc \ 0" के साथ समाप्त करेंगे, उदाहरण के लिए, यह लंबाई 4 की है, लेकिन वास्तव में केवल "abc" होनी चाहिए।


1
vector<char> vec;
//fill the vector;
std::string s(vec.begin(), vec.end());

क्या आप कोड के साथ कुछ स्पष्टीकरण भी जोड़ सकते हैं?
पॉल फ्लॉयड

1
C ++ 11 स्ट्रिंग लाइब्रेरी टेम्पलेट डिफ़ॉल्ट (1) स्ट्रिंग () के रूप में जाता है; कॉपी (2) स्ट्रिंग (कास्ट स्ट्रिंग और स्ट्र); प्रतिस्थापन (3) स्ट्रिंग (कास्ट स्ट्रिंग और स्ट्रैप, size_t pos, size_t len ​​= npos); सी-स्ट्रिंग (4) स्ट्रिंग (कास्ट चार * एस) से; बफर से (5) स्ट्रिंग (कास्ट चार * s, size_t n); fill (6) string (size_t n, char c); रेंज (7) टेम्पलेट <वर्ग InputIterator> string (InputIterator पहले, InputIterator अंतिम); initializer सूची (8) स्ट्रिंग (initializer_list <char> il); चाल (9) स्ट्रिंग (स्ट्रिंग और& str) noexcept; हम 7 वें टेम्पलेट का अनुसरण कर रहे हैं।
टेककट

हाय @TCCat! कृपया अपने अगले प्रश्न का उत्तर देने से पहले एक अच्छा उत्तर लिखें । तो अपने रहने का आनंद लें!
डिग्गी।

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