2011-11-02 7 views
7

मैं सोच रहा था कि Boost.Format किसी निश्चित-चौड़ाई/प्रीलोकेटेड बफर का उपयोग करके lib के द्वारा प्रबंधित गतिशील बफर के बजाय आउटपुट के रूप में समर्थन करता है?क्या प्रीस्टोकेटेड बफर के साथ Boost.Format का उपयोग करना संभव है?

है, आम तौर पर आप करते हैं चाहते हैं:

boost::format myfmt("arg1: %1%/arg2: %2%"); 
// e.g.: 
cout << (myfmt % 3.14 % 42); 
// or 
string s = boost::str(myfmt % "hey!" % "there!"); 

तो बूस्ट: स्वरूप lib स्वचालित रूप से पर्याप्त जगह आवंटित करने और आप के लिए "आउटपुट बफर" के प्रबंधन की देखभाल करेगा।

वहाँ Boost.Format के साथ एक पूर्वपरिभाषित गैर गतिशील बफर उपयोग करने के लिए किसी भी तरह से, कि है, की तरह कुछ अगर मैं सोच रहा था:

const size_t buf_sz = 512; 
char big_enough[buf_sz]; 
boost::format myfmt("arg1: %1%/arg2: %2%"); 
myfmt.attach_buffer(big_enough, buf_sz); 
myfmt % "hey!" % "there!" 
// big_enough buffer now contains the result string 

मैं जानता हूँ कि मैं सिर्फ उदाहरण में छान-बीन कर सकता है, डॉक्स और स्रोत, लेकिन समय एटीएम की कमी के अलावा। (और कुछ खोने की संभावना) यह जानना दिलचस्प होगा: यदि यह संभव नहीं है, तो यह अच्छा होगा अगर कोई यह समझा सके कि (यदि विशिष्ट हैं/विशिष्ट हैं) - क्या यह जानबूझकर था? क्या यह एपीआई अच्छी तरह से मेल नहीं खाता है? ...?

अस्वीकरण: यह प्रश्न प्रदर्शन के बारे में नहीं है!

+0

आपको क्या होने की जब आप कमरे से बाहर चलाने करना चाहते हैं? एक निश्चित बफ के लिए मैं snprintf का उपयोग करूंगा, लेकिन यह मैं हूं :) – nhed

+0

@nhed अगर यह फिट नहीं होता है, तो लाइब्रेरी या तो अपवाद फेंक सकता है या बस बफर भरना बंद कर सकता है ([विकल्प] के समान (http://www.boost.org/doc/libs/1_47_0/libs/format/doc/format.html#exceptions) पहले से ही उपलब्ध है) –

+0

मुझे यकीन नहीं है कि वे अपवाद लक्ष्य बफर – nhed

उत्तर

4

प्रारंभिक विचार

source को देखते हुए यह आप अपने खुद के संभाजक जो तब boost::format के आंतरिक धारा (internal_streambuf_t) द्वारा किया जाता है का उपयोग कर सकते है। क्या यह आपके मामले के लिए पर्याप्त होगा?

उदाहरण के लिए आप libstdC++ array_allocator

दुर्भाग्य boost::format भी जो जो अपने मामले में कोई समस्या हो सकती कस्टम संभाजक का उपयोग नहीं करते std::vector की एक जोड़ी का उपयोग करता है की तरह कुछ इस्तेमाल कर सकते हैं?

कैसे boost::format काम करता है

मैं boost::format के स्रोत में देखा और यह काम करता है कि यह कैसे (नीचे वर्णित str() है, << कॉल या तो str() या मानक std::ostream सामान का उपयोग करता है) है:

  • प्रारूप वर्ग कभी-कभी कस्टम आवंटक का उपयोग करते हुए सभी तर्कों और प्रारूप स्ट्रिंग को स्टोर करता है, कभी-कभी डिफ़ॉल्ट आवंटक
  • का उपयोग करते हुए str() इसे क्रॉस कहा जाता है एक नया std::string eates और यह परिणाम के लिए काफी बड़ी कस्टम संभाजक का उपयोग कर
  • यह तो परिणाम स्ट्रिंग
  • अंत में यह मूल्य द्वारा परिणाम स्ट्रिंग रिटर्न के लिए प्रारूप स्ट्रिंग से सभी तर्कों और स्थिर स्ट्रिंग टुकड़े संलग्न कर देता है बनाता है

तो, अंतिम परिणाम स्ट्रिंग प्रारूप वर्ग के अंदर संग्रहीत नहीं है, लेकिन आवश्यकता होने पर बनाई गई है।

तो यदि कस्टम कस्टम आवंटक का उपयोग करते समय आप परिणाम स्ट्रिंग का स्थान पा सकते हैं, तो यह केवल str() पर कॉल के बाद/उपलब्ध है। यह समझाया जाना चाहिए कि यह क्यों संभव नहीं है: स्वरूपित परिणाम कक्षा में "आउटपुट बफर" के अंदर कभी भी संग्रहीत नहीं होता है।

ऐसा क्यों है इस

क्यों वे इसे इस तरह मैं नहीं जानता कि क्या किया की तरह काम करता है। मुझे लगता है कि ऐसा इसलिए है क्योंकि आप सभी तर्कों के ज्ञात होने के बाद केवल परिणाम बना सकते हैं, यह परिणाम को संग्रहीत करने के लिए स्थान को बर्बाद कर देता है और आपको शायद किसी दिए गए प्रारूप/तर्क संयोजन के लिए केवल एक बार परिणाम की आवश्यकता होती है। इसलिए आवश्यकता होने पर इसे बनाने से अतिरिक्त काम नहीं होता है क्योंकि आमतौर पर str() केवल एक बार बुलाया जाता है।

समाधान

  • str() या << के आसपास कुछ आवरण बनाएँ और अपने निश्चित बफर
  • उपयोग एक (नीचे उदाहरण देखें) stream_buffer 'धारा' बफर में स्ट्रिंग के लिए
  • इनहेरिट में परिणाम नकल कक्षा और अपना खुद का str() फ़ंक्शन जोड़ें जो परिणाम को एक निश्चित बफर में संग्रहीत करता है।

संभव समाधान का उपयोग कर boost::iostreams (परीक्षण किया):

#include <iostream> 
#include <boost/format.hpp> 
#include <boost/iostreams/stream.hpp> 

int main() 
{ 
    char buffer[100]; 

    boost::iostreams::stream<boost::iostreams::array_sink> 
     stream(buffer, sizeof(buffer)); 

    stream << (boost::format("arg1 = %1%") % 12.5); 
    stream << '\0'; // make sure buffer contains 0-terminated string 

    std::cout << buffer << std::endl;  
} 
+0

उपयोगी जानकारी पर लागू होते हैं। मुझे लगता है कि आवंटकों के साथ थोड़ी सी समस्या यह है कि उन्हें केवल bad_alloc के माध्यम से विफलता की रिपोर्ट करने की अनुमति है, सही? –

+0

@ मार्टिन: मुझे लगता है कि आप सही हैं। इसके अलावा, मैंने प्रारूप के स्रोत में देखा और मुझे लगता है कि एक आवंटक का उपयोग करना मुश्किल है। मैंने जो चीजें पाईं, उनके साथ मैंने अपना जवाब अपडेट कर दिया है। – rve

+0

अच्छा काम! क्या मैं आपको सही ढंग से समझता हूं: आउटपुट स्ट्रिंग हर बार '.str()' कहा जाता है फिर से बनाया जाता है? –

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