स्ट्रिंग में wstring कैसे कन्वर्ट करें?


204

सवाल यह है कि wstring को स्ट्रिंग में कैसे परिवर्तित किया जाए?

मेरे पास अगला उदाहरण है:

#include <string>
#include <iostream>

int main()
{
    std::wstring ws = L"Hello";
    std::string s( ws.begin(), ws.end() );

  //std::cout <<"std::string =     "<<s<<std::endl;
    std::wcout<<"std::wstring =    "<<ws<<std::endl;
    std::cout <<"std::string =     "<<s<<std::endl;
}

टिप्पणी के साथ आउटपुट आउट लाइन है:

std::string =     Hello
std::wstring =    Hello
std::string =     Hello

लेकिन बिना ही है:

std::wstring =    Hello

क्या मिसाल में कुछ गलत है? क्या मैं ऊपर जैसा रूपांतरण कर सकता हूं?

संपादित करें

नया उदाहरण (कुछ उत्तरों को ध्यान में रखते हुए) है

#include <string>
#include <iostream>
#include <sstream>
#include <locale>

int main()
{
    setlocale(LC_CTYPE, "");

    const std::wstring ws = L"Hello";
    const std::string s( ws.begin(), ws.end() );

    std::cout<<"std::string =     "<<s<<std::endl;
    std::wcout<<"std::wstring =    "<<ws<<std::endl;

    std::stringstream ss;
    ss << ws.c_str();
    std::cout<<"std::stringstream =     "<<ss.str()<<std::endl;
}

आउटपुट है:

std::string =     Hello
std::wstring =    Hello
std::stringstream =     0x860283c

इसलिए स्ट्रिंग को वेस्टस्ट्रिंग को स्ट्रिंग में बदलने के लिए उपयोग नहीं किया जा सकता है।


4
बिना एनकोडिंग के भी आप यह सवाल कैसे पूछ सकते हैं?
डेविड हेफर्नन

5
@ एंटफॉर: आखिर उपयोग क्यों std::wstring? stackoverflow.com/questions/1049947/…
दिनांक

11
@ डेली अगर आपके पास पहले से यूटीएफ -16 के साथ एनकोड किया गया डेटा है, तो यूटीएफ -16 को हानिकारक माना जाता है या नहीं। और इसके लायक क्या है, मुझे नहीं लगता कि कोई भी परिवर्तन रूप हानिकारक है; क्या हानिकारक है लोग सोच रहे हैं कि वे यूनिकोड को समझते हैं जब वास्तव में वे नहीं करते हैं।
डेविड हेफर्नन

2
क्या इसके लिए एक क्रॉस-प्लेटफॉर्म समाधान होना चाहिए?
अली_बहू

2
@ डसेल सी ++ मानक किसी भी तरह से utf (utf-8 या utf-16) का उल्लेख नहीं करता है। एक लिंक मिला जहाँ यह कहता है कि utf-16 wstring से एन्कोड क्यों नहीं किया जा सकता है?
B:08овиЈ

जवाबों:


31

यहां अन्य सुझावों के आधार पर काम किया गया समाधान है:

#include <string>
#include <iostream>
#include <clocale>
#include <locale>
#include <vector>

int main() {
  std::setlocale(LC_ALL, "");
  const std::wstring ws = L"ħëłlö";
  const std::locale locale("");
  typedef std::codecvt<wchar_t, char, std::mbstate_t> converter_type;
  const converter_type& converter = std::use_facet<converter_type>(locale);
  std::vector<char> to(ws.length() * converter.max_length());
  std::mbstate_t state;
  const wchar_t* from_next;
  char* to_next;
  const converter_type::result result = converter.out(state, ws.data(), ws.data() + ws.length(), from_next, &to[0], &to[0] + to.size(), to_next);
  if (result == converter_type::ok or result == converter_type::noconv) {
    const std::string s(&to[0], to_next);
    std::cout <<"std::string =     "<<s<<std::endl;
  }
}

यह आमतौर पर लिनक्स के लिए काम करेगा, लेकिन विंडोज पर समस्याएं पैदा करेगा।


@Phillip: कोड का कौन सा भाग सी-लोकेल पर निर्भर करता है? क्या std::setlocale(LC_ALL, "");वास्तव में जरूरत है?
स्मरलिन

2
उपयोग std::wcout.imbue(locale)करने से नौकरी को अस्वस्थ करना चाहिए, और इसका यह लाभ है कि यह किसी भी वैश्विक स्थिति को नहीं बदलता है।
स्मरलिन

32
std::wstring_convertC ++ से इस शोर का एक बहुत ऊपर 11 wraps।
घनबाई

7
@Philipp, आपका क्या मतलब है "विंडोज पर समस्याएं पैदा करेगा"? किस तरह की परॆशानियाँ?
गिल्ली

1
उपरोक्त कोड देता है (जैसा कि कॉपी किया गया है) मुझे *** glibc detected *** test: malloc(): smallbin double linked list corrupted: 0x000000000180ea30 ***लाइनक्स 64-बिट (gcc 4.7.3) पर देता है। किसी और को यह अनुभव?
हॉगलियक्स

312

जैसा कि क्यूब्बी ने टिप्पणियों में से एक में बताया, std::wstring_convert(C ++ 11) एक साफ सरल समाधान प्रदान करता है (आपको इसकी आवश्यकता है #include <locale>और <codecvt>):

std::wstring string_to_convert;

//setup converter
using convert_type = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_type, wchar_t> converter;

//use converter (.to_bytes: wstr->str, .from_bytes: str->wstr)
std::string converted_str = converter.to_bytes( string_to_convert );

wcstombsइससे पहले कि मैं इस पर आया था मैं स्मृति के थकाऊ आवंटन और थकावट के संयोजन का उपयोग कर रहा था ।

http://en.cppreference.com/w/cpp/locale/wstring_convert

अद्यतन (2013/11/28)

एक लाइनर के रूप में ऐसा कहा जा सकता है (आपकी टिप्पणी के लिए धन्यवाद):

std::wstring str = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes("some string");

आवरण कार्यों को इस प्रकार कहा जा सकता है: (आपकी टिप्पणी के लिए अरमानश्चरज धन्यवाद)

std::wstring s2ws(const std::string& str)
{
    using convert_typeX = std::codecvt_utf8<wchar_t>;
    std::wstring_convert<convert_typeX, wchar_t> converterX;

    return converterX.from_bytes(str);
}

std::string ws2s(const std::wstring& wstr)
{
    using convert_typeX = std::codecvt_utf8<wchar_t>;
    std::wstring_convert<convert_typeX, wchar_t> converterX;

    return converterX.to_bytes(wstr);
}

नोट: वहाँ पर कि क्या कुछ विवाद है string/ wstringसंदर्भ के रूप में या (सी ++ के कारण 11 और संकलक अपडेट) शाब्दिक रूप में कार्य करने के लिए पारित किया जाना चाहिए। मैं निर्णय को लागू करने वाले व्यक्ति पर छोड़ दूंगा, लेकिन यह जानने लायक है।

नोट: मैं std::codecvt_utf8उपरोक्त कोड का उपयोग कर रहा हूं , लेकिन यदि आप UTF-8 का उपयोग नहीं कर रहे हैं, तो आपको उस उपयुक्त एन्कोडिंग में बदलने की आवश्यकता होगी जिसका आप उपयोग कर रहे हैं:

http://en.cppreference.com/w/cpp/header/codecvt


25
कृपया +1 : यह स्ट्रिंग रूपांतरण करने के लिए आधिकारिक C ++ मानक तरीका है। दूसरे तरीके को बदलने के लिए आप from_bytes का भी उपयोग कर सकते हैं। क्योंकि मुझे व्यक्तिगत रूप से वन-लाइनर्स पसंद हैं, यहाँ मेरा संस्करण है:std::wstring str = std::wstring_convert<std::codecvt_utf<wchar_t>>().from_bytes("some string");
Guss

7
लगता है जैसे en.cppreference.com/w/cpp/header/codecvt जी ++ 4.8.2 के अनुसार उपलब्ध नहीं है। दो s2ws और ws2s विधियाँ वर्तमान में linux के अंतर्गत काम नहीं करती हैं
बेगुई

5
ऐसा लगता है कि यह पदावनत है ( stackoverflow.com/a/42946556/211176 )। जब मैं इस कोड को चलाने की कोशिश करता हूं, तो मेरा कंपाइलर त्रुटियां फेंक देता है
adam_0


5
किसी को भी सी ++ के बारे में 17 और आगे संगतता (प्रतिवाद के कारण) में चिंता करने के लिए देखें: stackoverflow.com/a/18597384/6205379
टीमो

128

हल: http://forums.devshed.com/c-programming-42/wstring-to-string-444004.html

std::wstring wide( L"Wide" ); 
std::string str( wide.begin(), wide.end() );

// Will print no problemo!
std::cout << str << std::endl;

खबरदार कि यहां कोई कैरेक्टर सेट कन्वर्जन नहीं चल रहा है। यह क्या करता है बस wchar_tएक char- एक truncating रूपांतरण करने के लिए प्रत्येक iterated असाइन करने के लिए । यह std :: string c'tor का उपयोग करता है :

template< class InputIt >
basic_string( InputIt first, InputIt last,
              const Allocator& alloc = Allocator() );

जैसा कि टिप्पणियों में कहा गया है:

मान 0-127 वस्तुतः प्रत्येक एन्कोडिंग में समान हैं, इसलिए मानों को छोटा करना जो एक ही पाठ में 127 से कम परिणाम हैं। एक चीनी चरित्र में रखो और तुम विफलता देखेंगे।

-

विंडोज़ कोडपेज 1252 (विंडोज इंग्लिश डिफॉल्ट) और यूनिकोड के मानों 128-255 का मान ज्यादातर एक जैसा ही होता है, इसलिए यदि आप उन वर्णों का उपयोग कर रहे हैं जिन्हें सही मानों से अलग किया जाना चाहिए। (मुझे काम करने के लिए पूरी तरह से á और á की उम्मीद है, मुझे पता है कि काम पर हमारा कोड é के लिए इस पर निर्भर करता है, जिसे मैं जल्द ही पूरा करूंगा)

और ध्यान दें कि Win12520x80 - 0x9F में श्रेणी के कोड पॉइंट काम नहीं करेंगे । इसमें शामिल हैं , , , , ...œžŸ


2
विचित्र रूप से, यह विजुअल स्टूडियो 10 पर काम करता है। क्या चल रहा है? यह मूल स्ट्रिंग के सभी तत्वों के लिए wchar_t से char तक एक ट्रंकिटिंग एसिगमेंट का कारण बन सकता है।
पेड्रो लामारो

6
... जब यह किसी भी गैर-लैटिन वर्णों में जाता है।
जावारनर

8
@ PedroLamarão: मान 0-127 वस्तुतः हर एन्कोडिंग में समान हैं, इसलिए मानों को छोटा करना जो एक ही पाठ में 127 से कम परिणाम हैं। एक चीनी चरित्र में रखो और तुम विफलता देखेंगे।
मूविंग डक

3
@ PedroLamarão: मान खिड़कियों की 128-255 codepage 1252 (Windows अंग्रेजी डिफ़ॉल्ट) और मूल्यों यूनिकोड की 128-255 हैं ज्यादातर एक ही है, इसलिए यदि कि तेह कोड पृष्ठ पर आप उपयोग कर रहे है सबसे उन अक्षरों का सही करने के लिए छोटा कर दिया जाना चाहिए मान। (मुझे पूरी तरह से á और õ से काम करने की उम्मीद है, मुझे पता है कि काम पर हमारा कोड é के लिए इस पर निर्भर करता है, जिसे मैं जल्द ही ठीक कर दूंगा)
Mooing Duck

2
यह बहुत अच्छा काम करता है। MSVS 2015 और MSVS 2017 और MINGW / g ++ और clang ++। लेगिट ++ 1।
निकोस

11

लोकेल और उस सभी फैंसी सामानों को शामिल करने के बजाय, यदि आपको पता है कि FACT के लिए आपकी स्ट्रिंग परिवर्तनीय है तो बस यह करें:

#include <iostream>
#include <string>

using namespace std;

int main()
{
  wstring w(L"bla");
  string result;
  for(char x : w)
    result += x;

  cout << result << '\n';
}

इसका जीता जागता उदाहरण है


2
+1 क्योंकि यह एक सरल समाधान है जो कुछ परिदृश्यों के लिए काम करता है ("काम करता है" की एक ढीली परिभाषा के लिए, मैं जोड़ सकता हूं)।
रावेन

2
लगभग ऐसा ही है namar0x0309 के समाधान के रूप में, जो बहुत अधिक सुरुचिपूर्ण IMHO है। लेकिन वह सिर्फ मैं हूं।
13

मैं वास्तव में कम से कम संशोधन के साथ काम करने के लिए अपने कोड को
spiffied

9
-1 यदि आपके पास एक wstring है, तो संभावना है कि आप मल्टीबाइट पात्रों के साथ काम कर रहे हैं। यदि आप जान सकते हैं कि स्ट्रिंग तुच्छ रूप से परिवर्तनीय है, तो आप पहले स्थान पर एक wstring को नहीं संभालेंगे। अधिक संभावना है, आप एक अन्य पुस्तकालय के साथ काम कर रहे हैं जो आपसे उम्मीद करता है कि आप wstring को ठीक से संभाल लेंगे। Wchars ट्रंकिंग बस बाद में बग को ट्रेस करने के लिए एक कठिन भीख माँग रहा है। इसके अलावा, आपको "स्ट्रिंग परिणाम (w.begin (), w.end ());" यदि आप ऐसा करने जा रहे हैं, तो एक लूप से बचने के लिए जो कई वास्तविकताओं को ट्रिगर कर सकता है।
कियान

7

मेरा मानना ​​है कि आधिकारिक तरीका अभी भी थुगु codecvtपहलुओं पर जाना है (आपको कुछ प्रकार के स्थानीय-जागरूक अनुवाद की आवश्यकता है), जैसे कि

resultCode = use_facet<codecvt<char, wchar_t, ConversionState> >(locale).
  in(stateVar, scratchbuffer, scratchbufferEnd, from, to, toLimit, curPtr);

या ऐसा कुछ, मेरे पास काम करने वाला कोड नहीं है। लेकिन मुझे यकीन नहीं है कि इन दिनों कितने लोग उस मशीनरी का उपयोग करते हैं और कितने लोग बस मेमोरी के लिए पॉइंटर्स के लिए पूछते हैं और आईसीयू या कुछ अन्य लाइब्रेरी को गोर विवरणों को संभालने देते हैं।


7

कोड के साथ दो मुद्दे हैं:

  1. रूपांतरण const std::string s( ws.begin(), ws.end() );को विस्तृत वर्णों को उनके संकीर्ण प्रतिरूप में सही ढंग से मैप करने की आवश्यकता नहीं है। सबसे अधिक संभावना है, प्रत्येक विस्तृत चरित्र बस टाइपकास्ट किया जाएगा char
    इस समस्या का समाधान पहले से ही केम द्वारा उत्तर में दिया गया है और इसमें narrowलोकेल के ctypeपहलू को शामिल किया गया है।

  2. आप दोनों को std::coutऔर std::wcoutएक ही प्रोग्राम में आउटपुट लिख रहे हैं । दोनों coutऔर wcoutएक ही धारा (साथ जुड़े रहे हैं stdout) और एक ही धारा दोनों एक बाइट उन्मुख धारा (के रूप में के रूप में प्रयोग के परिणामों coutकरता है) और एक विस्तृत उन्मुख धारा (के रूप में wcoutकरता है) परिभाषित नहीं कर रहे हैं।
    सबसे अच्छा विकल्प संकीर्ण और विस्तृत आउटपुट को एक ही (अंतर्निहित) स्ट्रीम में मिलाने से बचना है। के लिए stdout/ cout/ wcout, आप के उन्मुखीकरण परिवर्तित करने का प्रयास कर सकते हैं stdoutजब व्यापक और संकीर्ण निर्गम (या विपरीत उपाध्यक्ष) के बीच स्विच:

    #include <iostream>
    #include <stdio.h>
    #include <wchar.h>
    
    int main() {
        std::cout << "narrow" << std::endl;
        fwide(stdout, 1); // switch to wide
        std::wcout << L"wide" << std::endl;
        fwide(stdout, -1); // switch to narrow
        std::cout << "narrow" << std::endl;
        fwide(stdout, 1); // switch to wide
        std::wcout << L"wide" << std::endl;
    }

हाँ, यह cout और wcout का उपयोग करके समस्या को ठीक करता है।
B21овиЈ

7

डिफ़ॉल्ट एन्कोडिंग पर:

  • विंडोज यूटीएफ -16।
  • लिनक्स UTF-8
  • MacOS UTF-8।

इस कोड में std :: string को std :: wstring और std :: wstring से std :: string में बदलने के दो रूप हैं। यदि आप Win32 को परिभाषित #if को नकारते हैं, तो आपको वही परिणाम मिलता है।

1. std :: string to std :: wstring

मल्टीबाइटटॉइडचेयर विनएपीआई

_mbstowcs_s_l

#if defined WIN32
#include <windows.h>
#endif

std::wstring StringToWideString(std::string str)
{
    if (str.empty())
    {
        return std::wstring();
    }
    size_t len = str.length() + 1;
    std::wstring ret = std::wstring(len, 0);
#if defined WIN32
    int size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, &str[0], str.size(), &ret[0], len);
    ret.resize(size);
#else
    size_t size = 0;
    _locale_t lc = _create_locale(LC_ALL, "en_US.UTF-8");
    errno_t retval = _mbstowcs_s_l(&size, &ret[0], len, &str[0], _TRUNCATE, lc);
    _free_locale(lc);
    ret.resize(size - 1);
#endif
    return ret;
}

2. std :: wstring to std :: string

WideCharToMultiByte WinAPI

_wcstombs_s_l

std::string WidestringToString(std::wstring wstr)
{
    if (wstr.empty())
    {
        return std::string();
    }
#if defined WIN32
    int size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &wstr[0], wstr.size(), NULL, 0, NULL, NULL);
    std::string ret = std::string(size, 0);
    WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &wstr[0], wstr.size(), &ret[0], size, NULL, NULL);
#else
    size_t size = 0;
    _locale_t lc = _create_locale(LC_ALL, "en_US.UTF-8");
    errno_t err = _wcstombs_s_l(&size, NULL, 0, &wstr[0], _TRUNCATE, lc);
    std::string ret = std::string(size, 0);
    err = _wcstombs_s_l(&size, &ret[0], size, &wstr[0], _TRUNCATE, lc);
    _free_locale(lc);
    ret.resize(size - 1);
#endif
    return ret;
}

3. विंडोज़ पर आपको WinAPI का उपयोग करके यूनिकोड प्रिंट करना होगा।

लिखावट सांत्वना

#if defined _WIN32
    void WriteLineUnicode(std::string s)
    {
        std::wstring unicode = StringToWideString(s);
        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), unicode.c_str(), unicode.length(), NULL, NULL);
        std::cout << std::endl;
    }

    void WriteUnicode(std::string s)
    {
        std::wstring unicode = StringToWideString(s);
        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), unicode.c_str(), unicode.length(), NULL, NULL);
    }

    void WriteLineUnicode(std::wstring ws)
    {
        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), ws.c_str(), ws.length(), NULL, NULL);
        std::cout << std::endl;
    }

    void WriteUnicode(std::wstring ws)
    {
        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), ws.c_str(), ws.length(), NULL, NULL);
    }

4. मुख्य कार्यक्रम पर।

#if defined _WIN32
int wmain(int argc, WCHAR ** args)
#else
int main(int argc, CHAR ** args)
#endif
{
    std::string source = u8"ÜüΩωЙ你月曜日\na🐕èéøÞǽлљΣæča🐕🐕";
    std::wstring wsource = L"ÜüΩωЙ你月曜日\na🐕èéøÞǽлљΣæča🐕🐕";

    WriteLineUnicode(L"@" + StringToWideString(source) + L"@");
    WriteLineUnicode("@" + WidestringToString(wsource) + "@");
    return EXIT_SUCCESS;
}

5. अंत में आपको कंसोल में यूनिकोड चार्ट के लिए एक शक्तिशाली और पूर्ण समर्थन की आवश्यकता है। मैं ConEmu की सलाह देता हूं और विंडोज पर डिफ़ॉल्ट टर्मिनल के रूप में सेट करता हूं । आपको Visual Studio को ConEmu पर हुक करने की आवश्यकता है। याद रखें कि Visual Studio की exe फ़ाइल devenv.exe है

वीसी ++ के साथ विजुअल स्टूडियो 2017 पर परीक्षण किया गया; एसटीडी = c ++ 17।

परिणाम

Result1


6

आप सीधे ctype facet की संकीर्ण विधि का उपयोग कर सकते हैं:

# किंकर्तव्यविमूढ़ <clocale>
# पता लगाएँ <स्थान>
# अलग करें <string>
#include <वेक्टर>

इनलाइन std :: स्ट्रिंग संकरा (std :: wstring const & text)
{
    std :: locale const loc ("");
    wchar_t const * से = text.c_str ();
    std :: size_t const len ​​= text.size ();
    std :: वेक्टर <char> बफर (लेन + 1);
    std :: use_facet <std :: ctype <wchar_t>> (loc) .narrow (से, + लेन, '_', और बफर [0]);
    वापसी std :: string (और बफर [0], और बफर [len]);
}

6

इस उत्तर को लिखने के समय, "कन्वर्ट स्ट्रिंग wstring" के लिए नंबर एक Google खोज आपको इस पृष्ठ पर लाएगा। मेरा उत्तर दर्शाता है कि स्ट्रिंग को wstring में कैसे परिवर्तित किया जाए, हालाँकि यह वास्तविक प्रश्न नहीं है, और मुझे शायद इस उत्तर को हटा देना चाहिए, लेकिन इसे बुरा रूप माना जाता है। आप इस StackOverflow उत्तर पर कूदना चाह सकते हैं , जो अब इस पृष्ठ से उच्च स्थान पर है।


यहाँ स्ट्रिंग, wstring और मिश्रित स्ट्रिंग स्थिरांक wstring के संयोजन का एक तरीका है। Wstringstream वर्ग का उपयोग करें।

#include <sstream>

std::string narrow = "narrow";
std::wstring wide = "wide";

std::wstringstream cls;
cls << " abc " << narrow.c_str() << L" def " << wide.c_str();
std::wstring total= cls.str();

13
यह स्ट्रिंग रूपांतरण के लिए नहीं है
poitroae

1
@ मिचेल क्या आप समझा सकते हैं? इस बारे में क्या गलत है? अधिक विवरण के बिना आपकी टिप्पणी उपयोगी नहीं है।
नैट

1
यह रूपांतरण को बदलने के लिए एक स्ट्रिंग है। यानी सवाल का उल्टा।
जेफ मैकक्लिंटॉक

4

केवल प्रकारों को परिवर्तित करने के अलावा, आपको स्ट्रिंग के वास्तविक प्रारूप के बारे में भी सचेत रहना चाहिए।

मल्टी-बाइट कैरेक्टर के लिए संकलन करते समय विजुअल स्टूडियो सेट करता है और विन एपीआई यूटीएफ 8 (वास्तव में विंडोज़ एन्कोडिंग जो कि विंडोज़-28591 है ) मानता है
जब यूनिकोड चरित्र के लिए संकलन दृश्य स्टूडियो सेट करता है और विन एपीआई UTF16 मानता है।

इसलिए, आपको स्ट्रिंग को UTF16 से UTF8 फॉर्मेट में बदलना होगा, न कि सिर्फ std :: string में कनवर्ट करना होगा।
कुछ गैर-लैटिन भाषाओं जैसे बहु-चरित्र प्रारूपों के साथ काम करते समय यह आवश्यक हो जाएगा।

विचार यह तय करना है कि std::wstring हमेशा UTF16 का प्रतिनिधित्व करता है ।
और std::string हमेशा UTF8 का प्रतिनिधित्व करता है ।

यह संकलक द्वारा लागू नहीं किया गया है, यह एक अच्छी नीति के लिए अधिक है। यूटीएफ 16 ( एल ) और यूटीएफ 8 ( यू 8 ) को परिभाषित करने के लिए मेरे द्वारा उपयोग किए जाने वाले स्ट्रिंग उपसर्गों पर ध्यान दें ।

2 प्रकारों के बीच कनवर्ट करने के लिए, आपको उपयोग करना चाहिए: std :: codecvt_utf8_utf16 <wchar_t>

#include <string>

#include <codecvt>

int main()
{

    std::string original8 = u8"הלו";

    std::wstring original16 = L"הלו";

    //C++11 format converter
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;

    //convert to UTF8 and std::string
    std::string utf8NativeString = convert.to_bytes(original16);

    std::wstring utf16NativeString = convert.from_bytes(original8);

    assert(utf8NativeString == original8);
    assert(utf16NativeString == original16);

    return 0;
}

3

मेरे मामले में, मुझे मल्टीबाइट चरित्र (MBCS) का उपयोग करना होगा, और मैं std :: string और std :: wstring का उपयोग करना चाहता हूं। और c ++ 11 का उपयोग नहीं कर सकते। इसलिए मैं mbstowcs और wcstombs का उपयोग करता हूं।

मैं नए का उपयोग करने के साथ एक ही कार्य करता हूं, [हटाएं], लेकिन यह धीमा है।

यह कैसे मदद कर सकता है: विभिन्न स्ट्रिंग प्रकारों के बीच कनवर्ट करें

संपादित करें

हालाँकि, wstring और स्रोत स्ट्रिंग में कनवर्ट करने के मामले में कोई वर्णमाला और मल्टी बाइट स्ट्रिंग नहीं है, यह काम नहीं कर रहा है। इसलिए मैं wcstombs को WideCharToMultiByte में बदलता हूं।

#include <string>

std::wstring get_wstr_from_sz(const char* psz)
{
    //I think it's enough to my case
    wchar_t buf[0x400];
    wchar_t *pbuf = buf;
    size_t len = strlen(psz) + 1;

    if (len >= sizeof(buf) / sizeof(wchar_t))
    {
        pbuf = L"error";
    }
    else
    {
        size_t converted;
        mbstowcs_s(&converted, buf, psz, _TRUNCATE);
    }

    return std::wstring(pbuf);
}

std::string get_string_from_wsz(const wchar_t* pwsz)
{
    char buf[0x400];
    char *pbuf = buf;
    size_t len = wcslen(pwsz)*2 + 1;

    if (len >= sizeof(buf))
    {
        pbuf = "error";
    }
    else
    {
        size_t converted;
        wcstombs_s(&converted, buf, pwsz, _TRUNCATE);
    }

    return std::string(pbuf);
}

EDIT 'wcstombs' के बजाय 'MultiByteToWideChar' का उपयोग करने के लिए

#include <Windows.h>
#include <boost/shared_ptr.hpp>
#include "string_util.h"

std::wstring get_wstring_from_sz(const char* psz)
{
    int res;
    wchar_t buf[0x400];
    wchar_t *pbuf = buf;
    boost::shared_ptr<wchar_t[]> shared_pbuf;

    res = MultiByteToWideChar(CP_ACP, 0, psz, -1, buf, sizeof(buf)/sizeof(wchar_t));

    if (0 == res && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
    {
        res = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0);

        shared_pbuf = boost::shared_ptr<wchar_t[]>(new wchar_t[res]);

        pbuf = shared_pbuf.get();

        res = MultiByteToWideChar(CP_ACP, 0, psz, -1, pbuf, res);
    }
    else if (0 == res)
    {
        pbuf = L"error";
    }

    return std::wstring(pbuf);
}

std::string get_string_from_wcs(const wchar_t* pcs)
{
    int res;
    char buf[0x400];
    char* pbuf = buf;
    boost::shared_ptr<char[]> shared_pbuf;

    res = WideCharToMultiByte(CP_ACP, 0, pcs, -1, buf, sizeof(buf), NULL, NULL);

    if (0 == res && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
    {
        res = WideCharToMultiByte(CP_ACP, 0, pcs, -1, NULL, 0, NULL, NULL);

        shared_pbuf = boost::shared_ptr<char[]>(new char[res]);

        pbuf = shared_pbuf.get();

        res = WideCharToMultiByte(CP_ACP, 0, pcs, -1, pbuf, res, NULL, NULL);
    }
    else if (0 == res)
    {
        pbuf = "error";
    }

    return std::string(pbuf);
}

मैं gcc 4.8 के साथ "wcstombs_s" का उपयोग कैसे कर सकता हूं? क्योंकि मुझे लगता है कि C ++ 11 फीचर है।
क्रिस्टियन

@ क्रिश्चियन आप इस फ़ंक्शन के "असुरक्षित" संस्करण का उपयोग कर सकते हैं wcstombs()
विजर

3

यह समाधान dk123 के समाधान में प्रेरित है , लेकिन एक स्थानीय आश्रित कोडेकवेट पहलू का उपयोग करता है। परिणाम UTF-8 के स्थान पर स्थानीय एन्कोडेड स्ट्रिंग में है (यदि यह लोकेल के रूप में सेट नहीं है)

std::string w2s(const std::wstring &var)
{
   static std::locale loc("");
   auto &facet = std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t>>(loc);
   return std::wstring_convert<std::remove_reference<decltype(facet)>::type, wchar_t>(&facet).to_bytes(var);
}

std::wstring s2w(const std::string &var)
{
   static std::locale loc("");
   auto &facet = std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t>>(loc);
   return std::wstring_convert<std::remove_reference<decltype(facet)>::type, wchar_t>(&facet).from_bytes(var);
}

मैं इसे खोज रहा था, लेकिन मुझे यह नहीं मिला। अंत में मैंने पाया कि मैं सही टाइपनेम के साथ फ़ंक्शन std::localeका उपयोग करने से सही पहलू प्राप्त कर सकता std::use_facet()हूं। उम्मीद है की यह मदद करेगा।


विज़ोर, स्थानीय आश्रित पहलू के साथ परिवर्तित करने के क्या फायदे हैं (यदि कोई हो)?
मार्क.2377

यदि आप सिस्टम से तार के साथ काम करते हैं, उदाहरण के लिए कंसोल इनपुट से।
विजर

1

मामले में किसी और रुचि रखता है: मैं एक वर्ग है कि दूसरे के स्थान पर जहाँ भी या तो एक प्रयोग किया जा सकता की जरूरत stringया wstringउम्मीद थी। निम्नलिखित वर्ग convertible_string, के आधार पर dk123 के समाधान , के साथ या तो एक प्रारंभ किया जा सकता है string, char const*, wstringया wchar_t const*और से को सौंपा जा सकता या परोक्ष परिवर्तित करने के लिए या तो एक stringया wstring(एक कार्यों है कि या तो ले में इतना पारित किया जा सकता)।

class convertible_string
{
public:
    // default ctor
    convertible_string()
    {}

    /* conversion ctors */
    convertible_string(std::string const& value) : value_(value)
    {}
    convertible_string(char const* val_array) : value_(val_array)
    {}
    convertible_string(std::wstring const& wvalue) : value_(ws2s(wvalue))
    {}
    convertible_string(wchar_t const* wval_array) : value_(ws2s(std::wstring(wval_array)))
    {}

    /* assignment operators */
    convertible_string& operator=(std::string const& value)
    {
        value_ = value;
        return *this;
    }
    convertible_string& operator=(std::wstring const& wvalue)
    {
        value_ = ws2s(wvalue);
        return *this;
    }

    /* implicit conversion operators */
    operator std::string() const { return value_; }
    operator std::wstring() const { return s2ws(value_); }
private:
    std::string value_;
};

1
मैं std::wstringक्लास में स्टोर करना चाहूंगा , स्टोर करने की तुलना में std::stringऔर एक रूपांतरण std::wstringप्राप्त करने के लिए कि कब क्या करना है std::wstring। क्योंकि std::wstringकुछ हद तक तेज है std::stringऔर यह बेहतर संगत है। यहां तक ​​कि इसके सेवन से याददाश्त भी बढ़ती है std::string
0xAA55

0
#include <boost/locale.hpp>
namespace lcv = boost::locale::conv;

inline std::wstring fromUTF8(const std::string& s)
{ return lcv::utf_to_utf<wchar_t>(s); }

inline std::string toUTF8(const std::wstring& ws)
{ return lcv::utf_to_utf<char>(ws); }

-1

मैं नीचे स्ट्रिंग का उपयोग करने के लिए wstring कन्वर्ट करने के लिए उपयोग कर रहा हूँ।

std::string strTo;
char *szTo = new char[someParam.length() + 1];
szTo[someParam.size()] = '\0';
WideCharToMultiByte(CP_ACP, 0, someParam.c_str(), -1, szTo, (int)someParam.length(), NULL, NULL);
strTo = szTo;
delete szTo;

आपको एक मानक हेडर ( <string>) और एक परिभाषा याद आ रही है WideCharToMultiByte()- क्या वह कुछ आवरण है std::wctomb()?
टोबे स्पाइट

-3
// Embarcadero C++ Builder 

// convertion string to wstring
string str1 = "hello";
String str2 = str1;         // typedef UnicodeString String;   -> str2 contains now u"hello";

// convertion wstring to string
String str2 = u"hello";
string str1 = UTF8string(str2).c_str();   // -> str1 contains now "hello"

3
कृपया समझाएं कि आपके उत्तर में क्या कर रहा है, अन्यथा यह विलोपित हो सकता है
CodeFanatic

1
UTF8string फ़ंक्शन कहाँ से आता है?
जीन-क्रिस्टोफ़ ब्लेंचर्ड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.