2015-09-09 10 views
5

पर रोकना, मैं एक फ़ाइल में संरचना से तार पढ़ रहा हूं जहां प्रत्येक स्ट्रिंग की निश्चित लंबाई है, '\0' पैडिंग के साथ। यदि संग्रहित स्ट्रिंग को पूरी लंबाई की आवश्यकता होती है तो वे शून्य-समाप्त नहीं होते हैं।एक्स वर्णों से std :: स्ट्रिंग का निर्माण, शून्य char

// char MyString[1000]; 
std::string stdmystring(MyString, ARRAYSIZE(MyString)); 

बहरहाल, यह प्रतियां गद्दी, भी:

मैं वर्तमान में इस तरह उन से बाहर std::string रों निर्माण कर रहा हूँ। मैं अब स्ट्रिंग को ट्रिम कर सकता हूं, लेकिन क्या पहली जगह कॉपी करने से रोकने के लिए एक सुरुचिपूर्ण और त्वरित तरीका है?

गति अंतरिक्ष से अधिक महत्वपूर्ण है, क्योंकि यह एक पाश में चलता है।

+0

आप आकार निर्धारित करने के लिए POSIX strnlen का उपयोग कर सकते हैं। (आपको ऐसा कुछ करना चाहिए, अन्यथा स्ट्रिंग :: आकार() हमेशा सरणी आकार होता है) –

+0

सच है, निश्चित रूप से एक अनुकूलन। मैं इसका उपयोग करूंगा यदि कोई भी आकार निर्धारित करने के लिए दूसरे लूप के बिना ऐसा कैसे करता है (जो मैंने सोचा था ...)। –

उत्तर

2

सरल समाधान हैं:

  1. बस पहले सही लंबाई

    • या तो strnlen का उपयोग गणना के रूप में डीटर
    • या std::find(MyString,MyString+ARRAYSIZE(MyString),'\0') सुझाव दिया जो IME किसी भी धीमी
    नहीं है

    ध्यान दें कि यदि आपकी स्ट्रिंग कैश में फिट बैठती है, तो वह एल होगा (कहते हैं कि तुम था अंतरिक्ष कम महत्वपूर्ण था) ikely हावी अतिरिक्त पाश

  2. आरक्षित लागत अधिकतम स्ट्रिंग आकार, और एक पाश पात्रों जोड़कर जब तक आप चौड़ाई निकास या एक नुल मारा (जैसे copy_until)

  3. बारे में वास्तव में एक अधिकतम आकार स्ट्रिंग nuls, इसे में strncpy साथ प्रारंभ बनाने के लिए, और वैकल्पिक रूप से unused nuls मिटा अगर तुम, आकार सही

दूसरा विकल्प केवल एक ही पाश का उपयोग करता है होना चाहता हूँ जबकि तीसरे कल्पना की दृष्टि से दो का उपयोग करता है (यह स्ट्रिंग में है सीटीओआर, और फिर प्रतिलिपि में)। हालांकि, प्रत्येक चरित्र का push_back सरल चरित्र असाइनमेंट से अधिक महंगा लगता है, इसलिए अगर मैं वास्तविकता में # 3 तेज़ था तो मुझे आश्चर्य नहीं होगा। प्रोफाइल और देखें!

+0

कम से कम विजुअल स्टूडियो में, ज्ञात आकार से स्ट्रिंग निर्माण memcpy का उपयोग करता है और किसी भी चीज़ से तेज़ तरीका है, इसलिए मैं डायटर की विधि के साथ जाऊंगा। –

2

खैर अगर आकार एक समस्या एक संभावित यह करने के लिए रास्ता नहीं है बनाने के लिए एक खाली std::string तो reserve() का उपयोग अंतरिक्ष संभवतः की जरूरत पहले से आवंटित करने के लिए और उसके बाद जब तक आप '\0' के पार चलो प्रत्येक चार जोड़ने है।

std::string stdmystring; 
stdmystring.reserve(MyString_MAX_SIZE) ; 
for(size_t i=0;i<MyString_MAX_SIZE && MyString[i]!='\0';++i); 
stdmystring+=MyString[i]; 

reserve() garanties आप एक स्मृति आवंटन के बाद से आप MAX_SIZE जानते हैं और स्ट्रिंग है जो की तुलना में बड़ा न हो।

+ = ऑपरेटर फ़ंक्शन को कॉल शायद इनलाइन किया जाएगा लेकिन इसे अभी भी जांचना होगा कि स्ट्रिंग की आवश्यक क्षमता है जो आपके मामले में अपर्याप्त है। असल में स्ट्रिंग की सटीक लंबाई को खोजने के लिए स्ट्रेल का उपयोग करके यह वही या बदतर हो सकता है ताकि आपको इसका परीक्षण करना पड़े।

+0

मुझे बाद में कुछ 'std :: string' कार्यान्वयन में देखना होगा, लेकिन मुझे लगता है कि यह संभव है कि' आरक्षित 'यहां एक निराशाजनक है: यह छोटे स्ट्रिंग अनुकूलन को रोक सकता है, जो ओपी के मामले के लिए महत्वपूर्ण हो सकता है, औसत और स्ट्रिंग लंबाई के आधार पर। – dyp

+0

हां यह सच है लेकिन यह स्थिति पर निर्भर करता है। छोटी स्ट्रिंग को आकार, क्षमता और पॉइंटर के लिए उपयोग की जाने वाली जगह पर फिट होना चाहिए, जो लंबे समय तक स्ट्रिंग के लिए अपने संबंधित आकार और कुछ ध्वज बिट/बिट्स को संक्षिप्त और लंबी स्ट्रिंग के बीच बताने के लिए उपयोग किया जाता है। आम तौर पर शॉर्ट स्ट्रिंग क्षमता 3 मशीन शब्दों से थोड़ी कम होती है। यदि औसत स्ट्रिंग आकार उस रिजर्व() में फिट हो सकता है तो वास्तव में प्रदर्शन के लिए खराब होगा, लेकिन यदि बहुत से लंबे तार हैं तो पहले आरक्षित नहीं हैं, कई आवंटन और प्रतिलिपि के कारण भी बदतर हो सकते हैं। – Abstraction

0

मुझे लगता है कि सबसे सरल तरीका आपके बाइट द्वारा अपने आंतरिक MyString सरणी को आवंटित करना है, हमेशा अंतिम बाइट को समाप्त कर दें, और std::string के सी-स्ट्रिंग कन्स्ट्रक्टर का उपयोग करें। (ध्यान रखें कि आपकी प्रक्रिया फ़ाइल पर I/O बाध्य होगी, इसलिए सी-स्ट्रिंग कन्स्ट्रक्टर का जो भी एल्गोरिदम ठीक होना चाहिए)।

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