2012-07-05 15 views
5

मैं वेक्टर के डेटा को क्रमबद्ध करने की कोशिश कर रहा हूं। नीचे दिए गए नमूने में मैं एक स्ट्रिंग को क्रमबद्ध करता हूं, और उसके बाद वेक्टर को वापस भेजता हूं, लेकिन उसी डेटा को प्राप्त नहीं करता जिसके साथ मैंने शुरुआत की थी। यह एक केस क्यों है?वेक्टर क्रमबद्धता

vector<size_t> v; 
v.push_back(1); 
v.push_back(2); 
v.push_back(3); 

string s((char*)(&v[0]), 3 * sizeof(size_t)); 

vector<size_t> w(3); 
strncpy((char*)(&w[0]), s.c_str(), 3 * sizeof(size_t)); 

for (size_t i = 0; i < w.size(); ++i) { 
    cout << w[i] << endl; 
} 

मैं उत्पादन

1 
2 
3 

प्राप्त करने के लिए, लेकिन इसके बजाय (gcc-4.5.1 पर) उत्पादन

1 
0 
0 

मिल

+0

@Mark: मुझे नहीं लगता कि ऐसी बात है है। –

उत्तर

4

त्रुटि strncpy को कॉल में शामिल है की उम्मीद है। जुड़े हुए पृष्ठ से:

तो src की लंबाई कम से कम n, strncpy() अशक्त बाइट्स के साथ गंतव्य के शेष के पैड है।

तो, के बाद धारावाहिक डेटा में पहली 0 बाइट पाया जाता है w के डेटा सरणी के शेष 0 रों साथ गद्देदार है।

बजाय एक बफर के रूप std::string का उपयोग कर के इसे ठीक करने के लिए एक for पाश का उपयोग करें, या std::copy

std::copy(&s[0], 
      &s[0] + v.size() * sizeof(size_t), 
      reinterpret_cast<char *>(w.data())); 

IMO,, बस एक char सरणी का उपयोग धारावाहिक डेटा रखने के लिए।

Example ideone

+0

'strncpy' पर अच्छा पकड़ है, मुझे लगता है कि" सुविधा "के बारे में पता नहीं था और यही कारण है उसकी कोड काम नहीं करता है के रूप में को विस्मित कर दिया गया था। –

+0

स्पष्टीकरण के लिए धन्यवाद। क्यों std :: कॉपी memcpy से बेहतर है? – typedef

+0

चूंकि आप पूर्णांक की सरणी की प्रतिलिपि बना रहे हैं, दोनों ही काम करेंगे। लेकिन मान लें कि वेक्टर में एक ऑब्जेक्ट था जिसमें कुछ संसाधन प्रबंधित किया गया था। memcpy ऑब्जेक्ट की बिटवाई प्रतिलिपि करेगा, जो संभवतः जिस तरह से आप कॉपी करना चाहते हैं उतना ही नहीं। दूसरी ओर, std :: प्रतिलिपि असाइनमेंट ऑपरेटर का आह्वान करेगी ताकि यह सुनिश्चित किया जा सके कि वस्तु सही तरीके से कॉपी की गई है। – Praetorian

2

strncpy पर असफल का एक विशाल ढेर है। यह आपके इनपुट पर जल्दी समाप्त हो जाएगा क्योंकि size_t में कुछ शून्य बाइट्स हैं, जो इसे नल टर्मिनेटर के रूप में व्याख्या करते हैं, उन्हें डिफ़ॉल्ट रूप से निर्मित 0. के रूप में छोड़कर। यदि आप बीई मशीन पर यह परीक्षण चलाते हैं, तो सभी 0 होंगे। std::copy का उपयोग करें।

-1

इस वेक्टर को स्ट्रिंग में क्रमबद्ध करने के लिए, आप पहले इस सदिश के प्रत्येक तत्व को एक स्ट्रिंग में परिवर्तित करना चाहते हैं जिसमें उस संख्या के असीसी प्रतिनिधित्व होते हैं, इस ऑपरेशन को int के क्रमिकरण कहा जा सकता है तार।

उदाहरण के लिए, एक पूर्णांक संभालने में 10 अंक है हम

// create temporary string to hold each element 
char intAsString[10 + 1]; 

फिर एक स्ट्रिंग के लिए पूर्णांक में बदल सकते हैं

sprintf(intAsString, "%d", v[0]); 

या

itoa(v[0], intAsString, 10 /*decimal number*/); 

तुम भी उपयोग कर सकते हैं ostringstream और < < ऑपरेटर की

अगर आप intAsString और वी की स्मृति सामग्री को देखने [0], वे बहुत अलग हैं, पहले ascii पत्र कि दशमलव संख्या प्रणाली में वी [0] के मूल्य का प्रतिनिधित्व (आधार 10) जबकि वी शामिल [0] में संख्या का द्विआधारी प्रतिनिधित्व शामिल है (क्योंकि कंप्यूटर कंप्यूटर नंबरों को स्टोर करता है)।

+1

यह मुझे स्पष्ट लगता है कि वह बाइनरी क्रमबद्धता चाहता है, टेक्स्ट क्रमबद्धता नहीं। इसके अलावा, सी ++ कोड में 'sprintf' और' itoa'? –

+0

अच्छी तरह से उसने आउटपुट को पकड़ने के लिए एक स्ट्रिंग बनाई, इसलिए मुझे लगता है कि वह टेक्स्ट क्रमबद्धता चाहता है। हालांकि टिप्पणी के लिए धन्यवाद :) –

+0

नहीं, स्ट्रिंग को वेक्टर में कॉपी किया गया है, और वेक्टर आउटपुट रखता है। स्ट्रिंग केवल एक बाइनरी बफर है। –

-1

सबसे सुरक्षित तरीका वेक्टर के माध्यम से सिर्फ पाश करने के लिए हो सकता है और अलग-अलग आकार 3 * sizeof (size_t) की एक चार सरणी में मान संग्रहीत होगा। इस तरह आप वेक्टर वर्ग कार्यान्वयन की आंतरिक संरचना पर निर्भरता नहीं रखते हैं।

+0

वेक्टर और स्ट्रिंग दोनों सन्निहित और सी ++ 11 में गद्दी के बिना होने की गारंटी कर रहे हैं, ताकि एक गैर मुद्दा है। –

संबंधित मुद्दे