वेक्टर की सामग्री कैसे प्रिंट करें?


281

मैं C ++ में एक वेक्टर की सामग्री को प्रिंट करना चाहता हूं, यहां मेरे पास है:

#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <vector>
#include <sstream>
#include <cstdio>
using namespace std;

int main()
{
    ifstream file("maze.txt");
    if (file) {
        vector<char> vec(istreambuf_iterator<char>(file), (istreambuf_iterator<char>()));
        vector<char> path;
        int x = 17;
        char entrance = vec.at(16);
        char firstsquare = vec.at(x);
        if (entrance == 'S') { 
            path.push_back(entrance); 
        }
        for (x = 17; isalpha(firstsquare); x++) {
            path.push_back(firstsquare);
        }
        for (int i = 0; i < path.size(); i++) {
            cout << path[i] << " ";
        }
        cout << endl;
        return 0;
    }
}

मैं वेक्टर की सामग्री को स्क्रीन पर कैसे प्रिंट करूं?


1
क्यों यह "काम नहीं कर रहा है"?
डिफॉल्ट

जवाबों:


392

अपने प्रश्न का उत्तर देने के लिए, आप एक पुनरावृत्ति का उपयोग कर सकते हैं:

std::vector<char> path;
// ...
for (std::vector<char>::const_iterator i = path.begin(); i != path.end(); ++i)
    std::cout << *i << ' ';

यदि आप लूप के लिए वेक्टर की सामग्री को संशोधित करना चाहते हैं, तो iteratorइसके बजाय का उपयोग करें const_iterator

लेकिन इसके बारे में बहुत कुछ कहा जा सकता है। यदि आप केवल एक उत्तर चाहते हैं जिसका आप उपयोग कर सकते हैं, तो आप यहां रुक सकते हैं; अन्यथा, पर पढ़ें।

ऑटो (C ++ 11) / टाइपडिफ

यह एक और समाधान नहीं है, लेकिन उपरोक्त iteratorसमाधान का पूरक है । यदि आप C ++ 11 मानक (या बाद में) का उपयोग कर रहे हैं, तो आप autoपठनीयता में मदद करने के लिए कीवर्ड का उपयोग कर सकते हैं :

for (auto i = path.begin(); i != path.end(); ++i)
    std::cout << *i << ' ';

लेकिन iगैर-कॉन्स्टेंट का प्रकार (यानी, संकलक std::vector<char>::iteratorके प्रकार के रूप में उपयोग करेगा i)।

इस स्थिति में, आप केवल एक का उपयोग कर सकते हैं typedef(C ++ 11 तक सीमित नहीं है, और वैसे भी उपयोग करने के लिए बहुत उपयोगी है):

typedef std::vector<char> Path;
Path path;
// ...
for (Path::const_iterator i = path.begin(); i != path.end(); ++i)
    std::cout << *i << ' ';

काउंटर

आप निश्चित रूप से, forलूप में अपनी स्थिति दर्ज करने के लिए पूर्णांक प्रकार का उपयोग कर सकते हैं :

for(int i=0; i<path.size(); ++i)
  std::cout << path[i] << ' ';

यदि आप ऐसा करने जा रहे हैं, तो कंटेनर के सदस्य प्रकारों का उपयोग करना बेहतर है, यदि वे उपलब्ध हैं और उपयुक्त हैं। इस कार्य के लिए std::vectorएक सदस्य प्रकार को बुलाया गया है size_type: यह वह sizeतरीका है जो विधि द्वारा लौटाया गया है ।

// Path typedef'd to std::vector<char>
for( Path::size_type i=0; i<path.size(); ++i)
  std::cout << path[i] << ' ';

क्यों नहीं इस iteratorसमाधान का उपयोग करें ? साधारण मामलों के लिए आप भी हो सकते हैं, लेकिन मुद्दा यह है कि iteratorवर्ग एक ऐसी वस्तु है जिसे इस काम के लिए और अधिक जटिल वस्तुओं के लिए डिज़ाइन किया गया है जहाँ यह समाधान आदर्श नहीं होने जा रहा है।

रेंज लूप के लिए (C ++ 11)

जेफरी का हल देखें । C ++ 11 (और बाद में) में आप नए रेंज-आधारित forलूप का उपयोग कर सकते हैं , जो इस तरह दिखता है:

for (auto i: path)
  std::cout << i << ' ';

चूंकि pathवस्तुओं का एक सदिश (स्पष्ट रूप से std::vector<char>) है, वस्तु iसदिश के प्रकार की वस्तु है (यानी, स्पष्ट रूप से, यह प्रकार की है char)। ऑब्जेक्ट iका एक मान होता है जो pathऑब्जेक्ट में वास्तविक आइटम की एक प्रति है । इस प्रकार, iलूप के सभी परिवर्तन pathअपने आप में संरक्षित नहीं हैं । साथ ही, यदि आप तथ्य यह है कि आप की प्रतिलिपि बनाई मान बदलने के लिए सक्षम होने के लिए नहीं करना चाहते हैं लागू करने के लिए चाहते हैं iपाश में, आप के प्रकार के लिए मजबूर कर सकते iहोने के लिए const charइस तरह:

for (const auto i: path)
  std::cout << i << ' ';

यदि आप आइटम को संशोधित करना चाहते हैं path, तो आप एक संदर्भ का उपयोग कर सकते हैं:

for (auto& i: path)
  std::cout << i << ' ';

और यहां तक ​​कि अगर आप संशोधित नहीं करना चाहते हैं path, अगर वस्तुओं की नकल महंगी है, तो आपको मूल्य द्वारा कॉपी करने के बजाय एक कास्ट संदर्भ का उपयोग करना चाहिए:

for (const auto& i: path)
  std::cout << i << ' ';

std :: प्रतिलिपि

यहोशू का जवाब देखिए । आप std::copyआउटपुट स्ट्रीम पर वेक्टर सामग्री की प्रतिलिपि बनाने के लिए STL एल्गोरिथ्म का उपयोग कर सकते हैं । यह एक सुरुचिपूर्ण समाधान है यदि आप इसके साथ सहज हैं (और इसके अलावा, यह बहुत उपयोगी है, न कि इस तरह के वेक्टर की सामग्री को मुद्रित करने के मामले में)।

std :: for_each

मैक्स का समाधान देखें । का उपयोग करते हुए std::for_eachइस सरल परिदृश्य के लिए overkill है, लेकिन यह एक बहुत ही उपयोगी समाधान है अगर तुम सिर्फ स्क्रीन पर प्रिंट की तुलना में अधिक करना चाहता था: का उपयोग कर std::for_eachआप क्या करने की अनुमति देता है किसी भी वेक्टर सामग्री पर (समझदार) आपरेशन।

अधिभार ओस्ट्रीम :: ऑपरेटर <<

क्रिस के जवाब को देखें , यह अन्य उत्तरों के लिए अधिक पूरक है क्योंकि आपको अभी भी ओवरलोडिंग में उपरोक्त समाधानों में से एक को लागू करने की आवश्यकता होगी। अपने उदाहरण में उन्होंने एक forलूप में एक काउंटर का उपयोग किया । उदाहरण के लिए, यह है कि आप जल्दी से यहोशू के समाधान का उपयोग कैसे कर सकते हैं :

template <typename T>
std::ostream& operator<< (std::ostream& out, const std::vector<T>& v) {
  if ( !v.empty() ) {
    out << '[';
    std::copy (v.begin(), v.end(), std::ostream_iterator<T>(out, ", "));
    out << "\b\b]";
  }
  return out;
}

किसी भी अन्य समाधान का उपयोग सीधा होना चाहिए।

निष्कर्ष

यहां प्रस्तुत कोई भी समाधान काम करेगा। यह आपके ऊपर है और कोड जिस पर "सबसे अच्छा" है। इससे अधिक विस्तृत कुछ भी संभवत: किसी अन्य प्रश्न के लिए सबसे अच्छा बचा है जहां पेशेवरों / विपक्ष का सही मूल्यांकन किया जा सकता है; लेकिन हमेशा की तरह उपयोगकर्ता वरीयता हमेशा एक हिस्सा निभाएगी: प्रस्तुत किए गए समाधानों में से कोई भी गलत नहीं है, लेकिन कुछ प्रत्येक व्यक्तिगत कोडर के लिए अच्छे लगेंगे।

परिशिष्ट

यह मेरे द्वारा पोस्ट किए गए पहले के एक विस्तारित समाधान है। चूँकि उस पोस्ट पर ध्यान दिया जा रहा था, मैंने इस पर विस्तार करने और यहाँ पोस्ट किए गए अन्य उत्कृष्ट समाधानों को संदर्भित करने का निर्णय लिया। मेरी मूल पोस्ट में एक टिप्पणी थी जिसमें उल्लेख किया गया था कि यदि आप एक लूप के अंदर अपने वेक्टर को संशोधित करने का इरादा कर रहे थे,for तो std::vectorतत्वों को एक्सेस करने के लिए दो तरीके प्रदान किए गए हैं: std::vector::operator[]जो सीमा की जाँच नहीं करता है, और std::vector::atजो सीमा जाँच करता है। दूसरे शब्दों में, atफेंक देंगे यदि आप वेक्टर के बाहर एक तत्व का उपयोग करने की कोशिश करते हैं और operator[]नहीं करेंगे। मैंने केवल इस टिप्पणी को जोड़ा है, मूल रूप से, किसी चीज का उल्लेख करने के लिए, जो किसी को पहले से ही नहीं होने के बारे में जानना उपयोगी हो सकता है। और मुझे अब कोई फर्क नहीं दिखता। इसलिए यह परिशिष्ट।


यदि आप लूप से 0गुजर रहे हैं vector::size()और वेक्टर को लूप के भीतर संशोधित नहीं किया गया है तो at()ओवरहेड की जाँच करने वाले अतिरिक्त सीमा का उपयोग करने और उकसाने की कोई आवश्यकता नहीं है । जैसा कि आपने सुझाव दिया, मैं एक पुनरावृत्तिकर्ता के साथ जाऊंगा।
एड एस।

1
@Ed: हाँ, वहाँ का उपयोग कर में कोई मतलब नहीं है atअगर पाश संशोधित में कुछ भी नहीं वेक्टर, लेकिन मैंने सोचा कि मैं यह उल्लेख था सिर्फ मामले में वेक्टर है पाश (के रूप में है कि हो सकता है unrecommended) में संशोधन किया और क्योंकि यह एक हो जाता है कभी नहीं उल्लेख और यह कम से कम, इसके बारे में उपयोगी हो सकता है।
जोरावर

लूप के लिए सीमा-आधारित संदर्भों का उपयोग करने के लिए फिर से लिखा जा सकता है, जो बड़ी उप-वस्तुओं के मामले में महत्वपूर्ण हो सकता है, इस प्रकार है:for (auto const &i: path) std::cout << i << ' ';
अंडरस्कोर_ड

@underscore_d: धन्यवाद। मैंने उस अनुभाग को साफ कर दिया है और मुझे आशा है कि यह अब और पूर्ण और थोड़ा स्पष्ट हो जाएगा।
जोरावर

"ओवरलोड ऑपरेटर <<" एक अच्छा समाधान नहीं है; ओवरलोडेड ऑपरेटर के कम से कम एक ऑपरेंड को आपके प्रोग्राम द्वारा परिभाषित एक वर्ग होना चाहिए, क्योंकि तर्क-निर्भर लुकअप के लिए
एमएम

218

ऐसा करने का एक बहुत आसान तरीका मानक कॉपी एल्गोरिदम के साथ है :

#include <iostream>
#include <algorithm> // for copy
#include <iterator> // for ostream_iterator
#include <vector>

int main() {
    /* Set up vector to hold chars a-z */
    std::vector<char> path;
    for (int ch = 'a'; ch <= 'z'; ++ch)
        path.push_back(ch);

    /* Print path vector to console */
    std::copy(path.begin(), path.end(), std::ostream_iterator<char>(std::cout, " "));

    return 0;
}

Ostream_iterator को इट्रेटर एडेप्टर कहा जाता है । यह धारा के बाहर प्रिंट करने के लिए (इस मामले में char) के प्रकार पर templatized है । cout(उर्फ कंसोल आउटपुट) वह स्ट्रीम है जिसे हम लिखना चाहते हैं, और अंतरिक्ष चरित्र ( " ") वही है जो हम वेक्टर में संग्रहीत प्रत्येक तत्व के बीच मुद्रित करना चाहते हैं।

यह मानक एल्गोरिथ्म शक्तिशाली है और इसलिए कई अन्य हैं। मानक पुस्तकालय की शक्ति और लचीलापन आपको वह देता है जो इसे इतना महान बनाता है। जरा कल्पना करें: आप एक वेक्टर को कोड की सिर्फ एक पंक्ति के साथ कंसोल पर प्रिंट कर सकते हैं । आपको विभाजक चरित्र के साथ विशेष मामलों से निपटने की ज़रूरत नहीं है। आप छोरों के बारे में चिंता करने की जरूरत नहीं है। मानक पुस्तकालय यह सब आपके लिए करता है।


3
क्या होगा अगर मेरा वेक्टर प्रकार का था vector<pair<int, struct node>>। इस वेक्टर को प्रिंट करने के लिए मैं उपरोक्त विधि का उपयोग कैसे करूं?
mtk

6
सीमांकक स्ट्रिंग प्रत्येक तत्व के बाद लिखा जाता है , बीच में नहीं, अर्थात, अंतिम के बाद भी। विशेष मामलों से निपटने की आवश्यकता हो सकती है यदि आप इसे केवल बीच में चाहते हैं, अर्थात, एक विभाजक के रूप में।
क्विगी

2
@mtk आप operator<<अपनी विशिष्ट जोड़ी <> के लिए एक फ़ंक्शन की घोषणा कर सकते हैं ।
जूताले

अतिरिक्त आउटरिंग सेपरेटर के बारे में ऊपर दिए गए टिप्पणी @Quigi: s के ऊपर टिप्पणी करते हुए, एक समान दृष्टिकोण दिखाने वाला उत्तर जोड़ा गया ।

@ शोले क्या कोई और रास्ता नहीं है?
thegreatcoder

69

C ++ 11 में अब आप लूप के लिए रेंज-आधारित का उपयोग कर सकते हैं :

for (auto const& c : path)
    std::cout << c << ' ';

यह केवल तभी काम करता है जब लूप के लिए रेंज के शरीर में वेक्टर का आकार नहीं बदला जाता है।
ब्रायन

8
@BrianP। हाँ। कंटेनर के तत्वों को प्रिंट करना कंटेनर की सीमा को संशोधित नहीं करता है।
जूता

यहाँ क्या बेहतर है - मूल्य कॉपी के रूप में या तत्व को कॉपी करने से बचने के लिए एक संदर्भ के रूप में?
kleinfreund

@kleinfreund यह वेक्टर की सामग्री पर निर्भर करता है। उदाहरण के लिए, सदिश के लिए char, संभावना है कि निरंतर संदर्भ से गुजरना वास्तव में मूल्य से अधिक महंगा है। लेकिन यहां हम सुपर माइक्रो ऑप्टिमाइजेशन की बात कर रहे हैं।
जूता

43

मुझे लगता है कि ऐसा करने का सबसे अच्छा तरीका यह है operator<<कि इस प्रोग्राम में अपने फंक्शन को जोड़कर सिर्फ ओवरलोड किया जाए:

#include <vector>
using std::vector;
#include <iostream>
using std::ostream;

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& v) {
    out << "{";
    size_t last = v.size() - 1;
    for(size_t i = 0; i < v.size(); ++i) {
        out << v[i];
        if (i != last) 
            out << ", ";
    }
    out << "}";
    return out;
}

फिर आप <<किसी भी संभावित वेक्टर पर ऑपरेटर का उपयोग कर सकते हैं , यह मानते हुए कि इसके तत्वों को भी ostream& operator<<परिभाषित किया गया है:

vector<string>  s = {"first", "second", "third"};
vector<bool>    b = {true, false, true, false, false};
vector<int>     i = {1, 2, 3, 4};
cout << s << endl;
cout << b << endl;
cout << i << endl;

आउटपुट:

{first, second, third}
{1, 0, 1, 0, 0}
{1, 2, 3, 4}

3
V.size () - 1 को एक इंट के रूप में संग्रहीत करना सटीक का एक संभावित नुकसान है। मैंने इसे एक स्वीकृत सहकर्मी द्वारा संपादित संपादित ( stackoverflow.com/revisions/23397700/5 ) में तय किया था, लेकिन इसके बाद इसे फिर से संपादित किया गया था ताकि परिशुद्धता के संभावित नुकसान को बहाल किया जा सके। मुझे लगता है कि व्यवहार में यह बहुत ज्यादा मायने नहीं रखता क्योंकि वैक्टर आमतौर पर इतने बड़े नहीं होते हैं।
JDiMatteo

इसे एक चर के रूप में संग्रहीत नहीं करने से कोड की पठनीयता कम हो जाती है, जो आपके द्वारा संपादित किए जाने वाले असहमति का एक हिस्सा है। मैंने का प्रकार बदल दिया lastहै size_t
क्रिस रेडफोर्ड

size_t last = v.size() - 1;बेमानी लग रहा है, आप लिंकif (i) out << ", "; से पहले शर्त का उपयोग कर सकते हैंout << v[i];
व्लादिमीर गमालियन

3
यह ऑपरेटर ADL द्वारा नहीं मिला है, क्योंकि यह इसके किसी भी तर्क के नामस्थान में नहीं है। तो यह किसी भी अन्य नामस्थान द्वारा छिपाया जाएगा operator<<उदाहरण
MM

यदि आप ऐसा करने जा रहे हैं, तो लूप मेंif (i != last) हर बार परीक्षण क्यों करें ? इसके बजाय, यदि कंटेनर खाली नहीं है, तो (ए) पहले तत्व को भेजें, और फिर (बी) शेष तत्वों को पहले विभाजक को प्रिंट करते हुए, शेष तत्वों को भेजें । कोई आंतरिक लूप टेस्ट (लूप की स्थिति के अलावा) की आवश्यकता होती है। केवल एक आउट-ऑफ-लूप टेस्ट की आवश्यकता होती है।
WhozCraig

22

कैसे के बारे में for_each+ भेड़ का बच्चा अभिव्यक्ति :

#include <vector>
#include <algorithm>
...
std::vector<char> vec;
...
std::for_each(
              vec.cbegin(),
              vec.cend(),
              [] (const char c) {std::cout << c << " ";} 
              );
...

बेशक, इस ठोस कार्य के लिए एक रेंज-आधारित सबसे सुरुचिपूर्ण समाधान है, लेकिन यह एक और भी कई संभावनाएं देता है।

व्याख्या

for_eachएल्गोरिथ्म एक लेता है इनपुट रेंज और एक प्रतिदेय वस्तु , रेंज के प्रत्येक तत्व पर इस वस्तु बुला। एक इनपुट रेंज को दो पुनरावृत्तियों द्वारा परिभाषित किया गया है । एक कॉल करने योग्य ऑब्जेक्ट एक फ़ंक्शन, फ़ंक्शन करने के लिए एक पॉइंटर, एक क्लास का एक ऑब्जेक्ट हो सकता है जो ओवरलोड करता है () operatorया इस मामले में, एक लैम्ब्डा अभिव्यक्ति । इस अभिव्यक्ति के लिए पैरामीटर वेक्टर से तत्वों के प्रकार से मेल खाता है।

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


11

बस कंटेनर को कंसोल पर कॉपी करें।

std::vector<int> v{1,2,3,4};
std::copy(v.begin(),v.end(),std::ostream_iterator<int>(std::cout, " " ));

उत्पादन करना चाहिए:

1 2 3 4

8

समस्या शायद पिछले लूप में है (x = 17; isalpha(firstsquare); x++):। यह लूप बिल्कुल नहीं चलेगा (यदि firstsquareगैर-अल्फ़ा है) या हमेशा के लिए चलेगा (यदि यह अल्फ़ा है)। कारण यह है कि वृद्धि के firstsquareरूप xमें नहीं बदलता है।


7

C ++ 11 में, लूप के लिए एक श्रेणी-आधारित एक अच्छा समाधान हो सकता है:

vector<char> items = {'a','b','c'};
for (char n : items)
    cout << n << ' ';

आउटपुट:

a b c 

6

का उपयोग कर, std::copyलेकिन अतिरिक्त अनुगामी विभाजक के बिना

एक वैकल्पिक / संशोधित दृष्टिकोण का उपयोग std::copy(जैसा कि मूल रूप से @JoshuaKravtiz उत्तर में उपयोग किया जाता है ) लेकिन अंतिम तत्व के बाद एक अतिरिक्त अनुगामी विभाजक को शामिल किए बिना:

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

template <typename T>
void print_contents(const std::vector<T>& v, const char * const separator = " ")
{
    if(!v.empty())
    {
        std::copy(v.begin(),
                  --v.end(),
                  std::ostream_iterator<T>(std::cout, separator));
        std::cout << v.back() << "\n";
    }
}

// example usage
int main() {
    std::vector<int> v{1, 2, 3, 4};
    print_contents(v);      // '1 2 3 4'
    print_contents(v, ":"); // '1:2:3:4'
    v = {};
    print_contents(v);      // ... no std::cout
    v = {1};
    print_contents(v);      // '1'
    return 0;
}

उदाहरण का उपयोग कस्टम POD प्रकार के कंटेनर पर लागू होता है:

// includes and 'print_contents(...)' as above ...

class Foo
{
    int i;
    friend std::ostream& operator<<(std::ostream& out, const Foo& obj);
public:
    Foo(const int i) : i(i) {}
};

std::ostream& operator<<(std::ostream& out, const Foo& obj)
{
    return out << "foo_" << obj.i; 
}

int main() {
    std::vector<Foo> v{1, 2, 3, 4};
    print_contents(v);      // 'foo_1 foo_2 foo_3 foo_4'
    print_contents(v, ":"); // 'foo_1:foo_2:foo_3:foo_4'
    v = {};
    print_contents(v);      // ... no std::cout
    v = {1};
    print_contents(v);      // 'foo_1'
    return 0;
}

5

अधिभार ऑपरेटर <<:

template<typename OutStream, typename T>
OutStream& operator<< (OutStream& out, const vector<T>& v)
{
    for (auto const& tmp : v)
        out << tmp << " ";
    out << endl;
    return out;
}

उपयोग:

vector <int> test {1,2,3};
wcout << test; // or any output stream

3

मुझे दो समस्याएं दिखाई देती हैं। जैसा कि for (x = 17; isalpha(firstsquare); x++)वहाँ बताया गया है कि या तो एक अनंत लूप है या कभी भी निष्पादित नहीं किया जाता है, और यह भी कि if (entrance == 'S')अगर प्रवेश चरित्र 'एस' से अलग है, तो पथ वेक्टर को धकेलने में कुछ भी नहीं है, इसे खाली करना और इस तरह स्क्रीन पर कुछ भी नहीं प्रिंट करना। आप path.empty()मुद्रण या मुद्रण के लिए बाद की जाँच कर सकते हैं path.size()

किसी भी तरह से, एक वेक्टर के बजाय एक स्ट्रिंग का उपयोग करना बेहतर नहीं होगा? आप एक सरणी की तरह स्ट्रिंग सामग्री तक पहुंच सकते हैं, वर्ण ढूंढ सकते हैं, सबस्ट्रिंग निकाल सकते हैं और स्ट्रिंग को आसानी से प्रिंट कर सकते हैं (बिना लूप के)।

स्ट्रिंग्स के साथ यह सब करना एक कम जटिल तरीके से लिखा जाना और समस्या को हल करने का आसान तरीका हो सकता है।


3

यह उत्तर जोरावर के उत्तर पर आधारित है, लेकिन मैं वहां कोई टिप्पणी नहीं छोड़ सकता।

आप Cbegin और cend का उपयोग करके ऑटो (C ++ 11) / typedef संस्करण का भाग बना सकते हैं

for (auto i = path.cbegin(); i != path.cend(); ++i)
    std::cout << *i << ' ';

1

C ++ 11`` में

for (auto i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';

for(int i=0; i<path.size(); ++i)
std::cout << path[i] << ' ';

यह उत्तर पहले से मौजूद उत्तरों की तुलना में कोई अतिरिक्त जानकारी नहीं देता है।
यश

0
#include<bits/stdc++.h>
using namespace std;

int main()
{
    vector <pair<string,int> > v;
    int n;
    cin>>n;
int i;
    for( i=0;i<n;i++)
    {
        int  end;
        string str;
        cin>>str;
        cin>>end;
        v.push_back(make_pair(str,end));
    }



for (int j=0;j<n;j++)
{
    cout<<v[j].first<< " "<<v[j].second<<endl;
}``
}

2
नमस्ते! Stackoverflow में आपका स्वागत है। यह बहुत अच्छा होगा यदि आप कोड स्निपेट के साथ कुछ स्पष्टीकरण शामिल कर सकते हैं कि आप क्या कर रहे हैं, और यह प्रश्न का उत्तर कैसे देता है।
स्लैबगोरब



0

उन लोगों के लिए जो रुचि रखते हैं: मैंने एक सामान्यीकृत समाधान लिखा है जो दोनों दुनिया का सबसे अच्छा लेता है, किसी भी प्रकार की सीमा के लिए अधिक सामान्यीकृत है और गैर-अंकगणितीय प्रकारों के लिए उद्धरण डालता है (स्ट्रिंग-जैसे प्रकारों के लिए वांछित)। इसके अतिरिक्त, इस दृष्टिकोण में कोई ADL समस्याएँ नहीं होनी चाहिए और 'आश्चर्य' से भी बचना चाहिए (क्योंकि यह मामला-दर-मामला आधार पर स्पष्ट रूप से जोड़ा जाता है):

template <typename T>
inline constexpr bool is_string_type_v = std::is_convertible_v<const T&, std::string_view>;

template<class T>
struct range_out {
  range_out(T& range) : r_(range) {
  }
  T& r_;
  static_assert(!::is_string_type_v<T>, "strings and string-like types should use operator << directly");
};

template <typename T>
std::ostream& operator<< (std::ostream& out, range_out<T>& range) {
  constexpr bool is_string_like = is_string_type_v<T::value_type>;
  constexpr std::string_view sep{ is_string_like ? "', '" : ", " };

  if (!range.r_.empty()) {
    out << (is_string_like ? "['" : "[");
    out << *range.r_.begin();
    for (auto it = range.r_.begin() + 1; it != range.r_.end(); ++it) {
      out << sep << *it;
    }
    out << (is_string_like ? "']" : "]");
  }
  else {
    out << "[]";
  }

  return out;
}

अब किसी भी सीमा पर उपयोग करना काफी आसान है:

std::cout << range_out{ my_vector };

स्ट्रिंग-जैसे चेक सुधार के लिए जगह छोड़ देता है। मेरे पास static_assertबचने के लिए मेरे समाधान में भी जांच है std::basic_string<>, लेकिन मैंने इसे सरलता के लिए यहां छोड़ दिया।


-1

आप अपना स्वयं का कार्य लिख सकते हैं:

void printVec(vector<char> vec){
    for(int i = 0; i < vec.size(); i++){
        cout << vec[i] << " ";
    }
    cout << endl;
}

-1

उन लोगों के लिए जो बिना छोरों के एक-लाइनर चाहते हैं:

मुझे विश्वास नहीं हो रहा है कि किसी के पास हालांकि यह है, लेकिन शायद यह अधिक सी-जैसे दृष्टिकोण के कारण है। वैसे भी, लूप के बिना ऐसा करना पूरी तरह से सुरक्षित है, एक-लाइनर में, यह मानते हुए कि std::vector<char>यह शून्य-समाप्त है:

std::vector<char> test { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!', '\0' };
std::cout << test.data() << std::endl;

लेकिन मैं इसे ostreamऑपरेटर में लपेटूंगा, जैसा कि @ ज़ोरावर ने सुझाव दिया, बस सुरक्षित रहने के लिए:

template <typename T>std::ostream& operator<< (std::ostream& out, std::vector<T>& v)
{
    v.push_back('\0'); // safety-check!
    out << v.data();
    return out;
}

std::cout << test << std::endl; // will print 'Hello, world!'

हम printfइसके बजाय का उपयोग करके समान व्यवहार प्राप्त कर सकते हैं :

fprintf(stdout, "%s\n", &test[0]); // will also print 'Hello, world!'

ध्यान दें:

अतिभारित ostreamऑपरेटर को वेक्टर को गैर-कास्ट के रूप में स्वीकार करना होगा। यह प्रोग्राम को असुरक्षित बना सकता है या गलत कोड पेश कर सकता है। इसके अलावा, चूंकि अशक्त-चरित्र को जोड़ा जाता है, इसलिए std::vectorहो सकता है कि एक पुनरावृत्ति हो। तो पुनरावृत्तियों के साथ छोरों के लिए उपयोग करना तेजी से संभव होगा।


1
1. fprintf(stdout, "%s\n", &test[0]);से अलग नहीं है std::cout << test.data(), दोनों को एक शून्य-समाप्त वेक्टर की आवश्यकता है। 2. "लेकिन मैं इसे ओस्ट्रीम ऑपरेटर में लपेटूंगा" << ऑपरेटर जो सही ऑपरेंड को संशोधित करता है एक बहुत बुरा विचार है।
होलीब्लैककैट

मैंने fprintf(stdout, "%s\n", &test[0]);लंबे समय तक कोड का उपयोग किया है , इसके बिना मुझे कभी कोई परेशानी नहीं हुई। दिलचस्प! और मैं मानता हूं कि ostreamऑपरेटर में वेक्टर को संशोधित करना इतना अच्छा नहीं है , लेकिन मैं मैन्युअल रूप से लूपिंग और पुनरावृत्तियों का उपयोग करके दोनों को नापसंद करता हूं । किसी भी तरह मुझे लगता है कि एक साधारण std::vector<char>पुस्तकालय की तरह साधारण संचालन के लिए इन चीजों को दूर छिपा देना चाहिए। लेकिन C ++ लगातार विकसित हो रहा है, यह जल्द ही आ सकता है।
き ん ワ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.