2010-01-13 5 views
7

ऐसे कई Win32 फ़ंक्शंस हैं जो बफर का पता लेते हैं, जैसे कि TCHAR[256], और उस बफर को कुछ डेटा लिखें। यह बफर के आकार से कम हो सकता है या यह संपूर्ण बफर हो सकता है।st32 :: स्ट्रिंग को Win32 फ़ंक्शंस के साथ कैसे मिलाएं जो char [] buffers लेते हैं?

अक्सर आप इसे एक लूप में कॉल करेंगे, उदाहरण के लिए स्ट्रीम या पाइप से डेटा पढ़ने के लिए। अंत में मैं कुशलता से उस स्ट्रिंग को वापस करना चाहता हूं जिसमें इस डेटा को पुनर्प्राप्त करने के लिए सभी पुनरावृत्त कॉलों का पूरा डेटा हो। मैं std::string का उपयोग करने के बारे में सोच रहा था क्योंकि यह + = जावा या सी #/StringBuilder.Append() विधियों के समान तरीके से अनुकूलित किया गया है, स्मृति की बजाय गति का पक्ष ले रहा है।

लेकिन मुझे यकीन नहीं है किWin32 फ़ंक्शंस के साथ सह-मिश्रण कैसे करें, क्योंकि ये फ़ंक्शनसे शुरू होते हैं। कोई सुझाव?

उत्तर

6

std::string एक समारोह c_str() कि इसके समकक्ष सी शैली स्ट्रिंग रिटर्न है। (const char *)

आगे, std::string असाइनमेंट ऑपरेटर ओवरलोड किया गया है जो इनपुट के रूप में सी-शैली स्ट्रिंग लेता है।

उदा। ssstd::string उदाहरण हो और एक सी शैली स्ट्रिंग तो interconversion के रूप में किया जा सकता है हो सकता है sc:

ss = sc; // from C-style string to std::string 
sc = ss.c_str(); // from std::string to C-style string 

अद्यतन:

के रूप में माइक वेलर ने कहा, UNICODE मैक्रो परिभाषित किया गया है, तो तार wchar_t* होंगे और इसलिए आपको std::wstring का उपयोग करना होगा।

+1

यह भी ध्यान दें कि यूनिकोड मैक्रो के मूल्य के आधार पर टीसीएचएआर बदल जाएगा। यदि यूनिकोड परिभाषित किया गया है, तो स्ट्रिंग wchar_t * होगी और आपको इसके बजाय std :: wstring का उपयोग करना होगा। –

+1

सीधे 'std :: string' आंतरिक बफर पर लिखना खतरनाक हो सकता है, क्योंकि स्ट्रिंग भी ऐसी चीजों को संग्रहीत करती है जो लंबाई हो सकती है जो आप कर सकते हैं। –

+0

इडान सही है। स्ट्रिंग बफर को लिखने वाले फ़ंक्शन के लिए std :: स्ट्रिंग का उपयोग न करें। – jmucchiello

6

std :: स्ट्रिंग की बजाय, मैं std::vector का उपयोग करने का सुझाव दूंगा, और v.size() का उपयोग करते समय &v.front() का उपयोग करने का सुझाव दूंगा। सुनिश्चित करें कि पहले से ही आवंटित स्थान है!

आपको std::string और बाइनरी डेटा से सावधान रहना होगा।

s += buf;//will treat buf as a null terminated string 
s += std::string(buf, size);//would work 
+1

शायद सीटीआर में वेक्टर के लिए प्रारंभिक आकार निर्धारित करना बुद्धिमान होगा, या वैकल्पिक रूप से 'आकार बदलें') पर कॉल करें। फिर बफर की लंबाई के रूप में इसका आकार() 'पास करें। –

+0

@ माइक वेलर: नीचे वोट के लिए धन्यवाद ... मुझे नहीं लगता कि आपका बिंदु क्या है ... कैसे .data() के बारे में? बेशक मुझे पता है कि .c_str() क्या करता है, लेकिन ओपी ने कहा कि कार्य एक बफर में लेते हैं, और मनमाने ढंग से बाइनरी डेटा के लिए, std :: string के बजाय std :: vector का उपयोग करना बेहतर होता है। –

+0

ध्यान दें कि आपको या तो आकार-सेटिंग कन्स्ट्रक्टर के साथ वेक्टर बनाने की आवश्यकता है, या उस पर आकार बदलें() पर कॉल करें। –

11

तर्क इनपुट केवल उपयोग std::string इस

std::string text("Hello"); 
w32function(text.c_str()); 

की तरह तर्क इनपुट/आउटपुट उपयोग std::vector<char> बजाय इस तरह है, तो यह है:

std::string input("input"); 
std::vector<char> input_vec(input.begin(), input.end()); 
input_vec.push_back('\0'); 
w32function(&input_vec[0], input_vec.size()); 
// Now, if you want std::string again, just make one from that vector: 
std::string output(&input_vec[0]); 

तर्क है आउटपुट-केवल भी std::vector<Type> का उपयोग इस प्रकार करते हैं:

// allocates _at least_ 1k and sets those to 0 
std::vector<unsigned char> buffer(1024, 0); 
w32function(&buffer[0], buffer.size()); 
// use 'buffer' vector now as you see fit 

यदि आवश्यक हो तो आप std::basic_string<TCHAR> और std::vector<TCHAR> का भी उपयोग कर सकते हैं।

आप स्कॉट मेयर्स द्वारा प्रभावी एसटीएल पुस्तक में विषय पर और अधिक पढ़ सकते हैं।

2
  • आपको एक संगत स्ट्रिंग प्रकार की आवश्यकता है: typedef std::basic_string<TCHAR> tstring; एक अच्छा विकल्प है।

  • इनपुट केवल तर्क के लिए, आप .c_str() विधि का उपयोग कर सकते हैं।

  • बफ़र्स के लिए, विकल्प थोड़ा कम स्पष्ट है:

std :: basic_string एसटीडी की तरह सन्निहित संग्रहण का उपयोग करना इसकी गारंटी नहीं है :: वेक्टर है। हालांकि, मैंने देखा है कि सभी std :: basic_string कार्यान्वयन संगत भंडारण का उपयोग करते हैं, और सी ++ मानकों की समिति मानक में दोषपूर्ण गारंटी को मानने पर विचार करती है। दोष को C++ 0x ड्राफ्ट में ठीक किया गया है।

यदि आप नियमों को कभी भी थोड़ा मोड़ने के इच्छुक नहीं हैं - कोई नकारात्मक नतीजे नहीं - आप & (* aString.begin()) का उपयोग लंबाई aString.size() की एक टीसीएचएआर बफर के सूचक के रूप में कर सकते हैं। अन्यथा, आप अब के लिए std :: वेक्टर के साथ अटक गए हैं।

इस मौजूदा अभ्यास कार्यान्वयन करने वालों अधिक स्वतंत्रता नहीं देता मानकीकरण नहीं:

यहाँ सी ++ मानक समिति सन्निहित स्ट्रिंग भंडारण के बारे में क्या कहना है है। हमने सोचा कि यह एक दशक पहले हो सकता है। लेकिन विक्रेताओं के पास दोनों कार्यान्वयन के साथ बोली जाती हैं, और एलडब्ल्यूजी मीटिंग्स में उनकी आवाज के साथ बोली जाती है। कार्यान्वयन संगत होने के बावजूद मानक कहता है कि कोई फर्क नहीं पड़ता। तो मानक स्ट्रिंग क्लाइंट को अधिक डिज़ाइन विकल्प दे सकता है।

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