2008-11-03 16 views
63

CString काफी आसान है, जबकि std::string एसटीएल कंटेनर के साथ अधिक संगत है। मैं hash_map का उपयोग कर रहा हूं। हालांकि, hash_mapCString को कुंजी के रूप में समर्थन नहीं करता है, इसलिए मैं CString को std::string में परिवर्तित करना चाहता हूं।CString और :: std :: string :: std :: wstring को दूसरे में कैसे परिवर्तित करें?

CString हैश फ़ंक्शन लिखने में काफी समय लगता है।

CString -----> std::string 

मैं यह कैसे कर सकता हूं?

std::string -----> CString: 

inline CString toCString(std::string const& str) 
{ 
    return CString(str.c_str()); 
} 

क्या मैं सही हूँ?


संपादित करें:

मैं कैसे परिवर्तित कर सकते हैं wstring, एक दूसरे के लिए CString:

यहाँ अधिक सवाल कर रहे हैं?

//wstring -> CString, 
std::wstring src; 
CString result(src.c_str()); 
//CString->wstring. 
CString src; 
::std::wstring des(src.GetString()); 

वहाँ किसी भी समस्या है?

मैं std::wstring, std::string को एक-दूसरे से कैसे परिवर्तित कर सकता हूं?

+3

मैं यह कर नहीं होगा ... दो अलग तार प्रकार का उपयोग करना काफी बुरा है, लेकिन हर बार जब आप एक नक्शे के साथ कुछ करना कन्वर्ट करने के लिए आ रही हैं? भयानक लगता है। बस सुसंगत रहें और std :: स्ट्रिंग का उपयोग करें। अगर किसी कारण से आप वास्तव में सोचते हैं कि सीएसटींग बेहतर है, तो इसके लिए हैश फ़ंक्शन को परिभाषित करें ताकि आपका हैश_मैप इसका उपयोग कर सके, यह आपके कोड में उलझन में दोगुनी से कहीं बेहतर है। – GManNickG

+2

असल में, यदि सभी कोड स्वयं द्वारा लिखे गए हैं तो यह सुसंगत रहेगा, लेकिन कुछ ओपनोरस्ड प्रोजेक्ट हैं जैसे कि फ्रीमेज स्क्लाइट का उपयोग किया जाता है। मैं वहां कोड संशोधित नहीं कर सकता। – user25749

उत्तर

78

CodeGuru के अनुसार:

CStringstd::string रहे हैं:

CString cs("Hello"); 
std::string s((LPCTSTR)cs); 

लेकिन:std::string हमेशा एक LPCTSTR से निर्माण नहीं कर सकते। यानी यूनिकोड के निर्माण के लिए कोड विफल हो जाएगा।

std::string के रूप में केवल से LPSTR/LPCSTR, एक प्रोग्रामर जो कुलपति ++ 7.x या बेहतर उपयोग करता रूपांतरण वर्गों का उपयोग कर सकते एक मध्यस्थ के रूप में इस तरह के रूप में CT2CA निर्माण कर सकते हैं।

CString cs ("Hello"); 
// Convert a TCHAR string to a LPCSTR 
CT2CA pszConvertedAnsiString (cs); 
// construct a std::string using the LPCSTR input 
std::string strStd (pszConvertedAnsiString); 

std::string to CString: (Visual Studio's CString FAQs... से)

std::string s("Hello"); 
CString cs(s.c_str()); 

CStringT दोनों चरित्र या चौड़े चरित्र तार से निर्माण कर सकते हैं। यानी यह char* (यानी LPSTR) या wchar_t* (LPWSTR) से परिवर्तित कर सकता है।

दूसरे शब्दों में, चार-विशेषज्ञता (CStringT का) यानी CStringA, wchar_t -specilization CStringW, और TCHAR -specialization CString या तो char या चौड़ी-चरित्र का निर्माण किया जा सकता है, अशक्त समाप्त (शून्य-समाप्ति यहाँ बहुत महत्वपूर्ण है) स्ट्रिंग स्रोत।

NUL-समाप्ति की आवश्यकता नहीं है:
Althoug IInspectable "नल-समाप्ति" भाग in the comments हरजाना।
CStringT में रूपांतरण रचनाकार हैं जो एक स्पष्ट लंबाई तर्क लेते हैं। इसका मतलब यह भी है कि आप CStringTstd::string ऑब्जेक्ट्स से NUL वर्णों के साथ ऑब्जेक्ट्स बना सकते हैं।

+2

एरर ... आपका स्वागत है :) विस्तृत स्पष्टीकरण के लिए सिद्धार्थ राव के लिए धन्यवाद। – VonC

+0

अंतिम अनुच्छेद पूरी तरह से सही नहीं है। 'एनयूएल 'समाप्ति की आवश्यकता नहीं है। ['CStringT'] (http://msdn.microsoft.com/en-us/library/cws1zdt8.aspx) में रूपांतरण कन्स्ट्रक्टर हैं जो एक स्पष्ट लंबाई तर्क लेते हैं। इसका अर्थ यह भी है कि आप 'std :: string' ऑब्जेक्ट्स से एम्बेडेड' NUL' वर्णों के साथ 'CStringT' ऑब्जेक्ट्स बना सकते हैं। – IInspectable

+0

@ अप्रत्याशित अच्छा बिंदु। मैंने अधिक दृश्यता के उत्तर में आपकी टिप्पणी शामिल की है। – VonC

33

std::basic_string<TCHAR> बजाय std::string का उपयोग करके कि समाधान है और यह अपने चरित्र सेटिंग कुछ भी हो ठीक काम करना चाहिए।

+2

यह विधि अधिक सरल है – user25749

+5

मुझे टाइपिफ़ करना पसंद है कि सुविधा और परिचितता के लिए: 'typedef std :: basic_string tstring' –

-1

यदि आप अन्य तारों के प्रकारों के बीच आसानी से कनवर्ट करना चाहते हैं, तो शायद _bstr_t कक्षा अधिक उपयुक्त होगी? यह char, wchar_t और BSTR के बीच कनवर्टन का समर्थन करता है।

+1

-1' CString' आपके द्वारा नामित सभी रूपांतरणों को पहले से ही करता है। और यह 3 साल पहले भी किया था। COM वातावरण में उपयोग के लिए एक प्रकार का सुझाव देने में कोई मतलब नहीं है। – IInspectable

4

यदि आप कुछ और सी ++ चाहते हैं - जैसे, मैं यही उपयोग करता हूं। हालांकि यह बूस्ट पर निर्भर करता है, यह सिर्फ अपवादों के लिए है। आप केवल एसटीएल और WideCharToMultiByte() Win32 API कॉल पर निर्भर रहने के लिए इसे छोड़कर आसानी से हटा सकते हैं।

#include <string> 
#include <vector> 
#include <cassert> 
#include <exception> 

#include <boost/system/system_error.hpp> 
#include <boost/integer_traits.hpp> 

/** 
* Convert a Windows wide string to a UTF-8 (multi-byte) string. 
*/ 
std::string WideStringToUtf8String(const std::wstring& wide) 
{ 
    if (wide.size() > boost::integer_traits<int>::const_max) 
     throw std::length_error(
      "Wide string cannot be more than INT_MAX characters long."); 
    if (wide.size() == 0) 
     return ""; 

    // Calculate necessary buffer size 
    int len = ::WideCharToMultiByte(
     CP_UTF8, 0, wide.c_str(), static_cast<int>(wide.size()), 
     NULL, 0, NULL, NULL); 

    // Perform actual conversion 
    if (len > 0) 
    { 
     std::vector<char> buffer(len); 
     len = ::WideCharToMultiByte(
      CP_UTF8, 0, wide.c_str(), static_cast<int>(wide.size()), 
      &buffer[0], static_cast<int>(buffer.size()), NULL, NULL); 
     if (len > 0) 
     { 
      assert(len == static_cast<int>(buffer.size())); 
      return std::string(&buffer[0], buffer.size()); 
     } 
    } 

    throw boost::system::system_error(
     ::GetLastError(), boost::system::system_category); 
} 
5

यह रूपांतरण जहां लंबाई निर्दिष्ट किया जाता है का उपयोग कर std::string को CString कन्वर्ट करने के लिए और अधिक कुशल है।

CString someStr("Hello how are you"); 
std::string std(somStr, someStr.GetLength()); 

तंग लूप में यह एक महत्वपूर्ण प्रदर्शन सुधार करता है। मेरे लिए

+1

मुझे इसका उपयोग करके एक त्रुटि मिली: 'पैरामीटर 1 को' CString 'से' const std :: basic_string <_Elem, _Traits, _Alloc> और '' –

1

काम करता है:

std::wstring CStringToWString(const CString& s) 
{ 
    std::string s2; 
    s2 = std::string((LPCTSTR)s); 
    return std::wstring(s2.begin(),s2.end()); 
} 

CString WStringToCString(std::wstring s) 
{ 
    std::string s2; 
    s2 = std::string(s.begin(),s.end()); 
    return s2.c_str(); 
} 
1

यह एक साल का जवाब है, जहां वह/वह समाधान प्रदान करने के लिए ऊपर का पालन करें:

CString someStr("Hello how are you"); 
std::string std(somStr, someStr.GetLength()); 

यह उपयोगी भी जब एक गैर विशिष्ट सी परिवर्तित है - एक std :: स्ट्रिंग के लिए स्ट्रिंग

मेरे लिए एक केस केस प्री-आवंटित चार सरणी (जैसे सी-स्ट्रिंग) था, लेकिन यह एनयूएल समाप्त नहीं हुआ था। (यानी एसएचए पचाने)। उपर्युक्त वाक्यविन्यास मुझे चार सरणी के SHA पाचन की लंबाई निर्दिष्ट करने की अनुमति देता है ताकि std :: स्ट्रिंग को एनयूएल चार को समाप्त करने की आवश्यकता न हो, जो हो सकता है या नहीं भी हो सकता है।

जैसे:

unsigned char hashResult[SHA_DIGEST_LENGTH];  
auto value = std::string(reinterpret_cast<char*>hashResult, SHA_DIGEST_LENGTH); 
+0

' में परिवर्तित नहीं किया जा सकता है, यदि आप अपने संशोधन संलग्न के साथ साल का उत्तर संपादित करते हैं तो यह बेहतर होगा या साल के जवाब पर टिप्पणी की? – Kmeixner

+0

मैंने कोशिश की ... लेकिन स्टैक ओवरफ्लो ने मुझे करने और संपादित करने की क्षमता नहीं दी है। – Neil

1

यह ठीक काम करता है:

//Convert CString to std::string 
inline std::string to_string(const CString& cst) 
{ 
    return CT2A(cst.GetString()); 
} 
0

सभी अन्य उत्तर काफी पता है कि मैं क्या देख रहा था नहीं था जिसके लिए मक्खी पर CString कन्वर्ट करने के लिए के रूप में स्टोर करने के लिए विरोध किया था एक चर में परिणाम।

समाधान उपर्युक्त जैसा है लेकिन हमें एक अज्ञात वस्तु को तुरंत चालू करने के लिए एक और कदम की आवश्यकता है। मैं एक उदाहरण के साथ चित्रण कर रहा हूँ। यहां मेरा फ़ंक्शन है जिसे std::string की आवश्यकता है लेकिन मेरे पास CString है।

void CStringsPlayDlg::writeLog(const std::string &text) 
{ 
    std::string filename = "c:\\test\\test.txt"; 

    std::ofstream log_file(filename.c_str(), std::ios_base::out | std::ios_base::app); 

    log_file << text << std::endl; 
} 

आपके पास CString होने पर इसे कैसे कॉल करें?

std::string firstName = "First"; 
CString lastName = _T("Last"); 

writeLog(firstName + ", " + std::string(CT2A(lastName)));  

ध्यान दें कि अंतिम पंक्ति एक सीधा समान किरदार नहीं है लेकिन हम एक अनाम std::string वस्तु बनाने और उसके निर्माता के माध्यम से CString की आपूर्ति कर रहे हैं।

0

क्यों CString से CStringA पर string कन्स्ट्रक्टर के अंदर क्यों नहीं डाला गया?

 CString s1("SomeString"); 
     string s2((CStringA)s1); 
संबंधित मुद्दे