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

উদাহরণে কিছু ভুল আছে? আমি কি উপরের মত রূপান্তর করতে পারি?

সম্পাদনা

নতুন উদাহরণ (কিছু উত্তর গ্রহণ করা) is

#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
@tenfour: কেন মোটেই ব্যবহার করবেন std::wstring? stackoverflow.com/questions/1049947/…
ডাল

11
@ ডালে আপনার যদি ইতিমধ্যে ইউটিএফ -১ with এর সাথে এনকোডড ডেটা থাকে, ইউটিএফ -১ 16 কে ক্ষতিকারক বলে বিবেচনা করা হয় বা না হয় কিছুটা মোট। এবং এটির জন্য মূল্যবান, আমি মনে করি না যে কোনও রূপান্তর ফর্ম ক্ষতিকারক; ক্ষতিকারক কী তা হ'ল লোকেরা ভাবছে যে তারা ইউনিকোড বুঝতে পারে যখন বাস্তবে তারা না দেয়।
ডেভিড হেফারনান

2
এটি একটি ক্রস প্ল্যাটফর্ম সমাধান হতে হবে?
আলী_বাহু

2
@ ডাল সি ++ স্ট্যান্ডার্ড কোনওভাবেই utf উল্লেখ করে না (utf-8 বা utf-16)। একটি লিঙ্ক পেয়েছেন যেখানে এতে বলা হয়েছে কেন utf-16 wstring এর সাথে এনকোড করতে পারে না?
BЈовић

উত্তর:


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;
  }
}

এটি সাধারণত লিনাক্সের জন্য কাজ করবে তবে উইন্ডোজে সমস্যা তৈরি করবে।


@ ফিলিপ: কোডের কোন অংশটি সি-লোকালে নির্ভর করে? হয় std::setlocale(LC_ALL, "");সত্যিই প্রয়োজন?
স্মারলিন

2
ব্যবহারের std::wcout.imbue(locale)কাজটি পাশাপাশি করা উচিত, এবং এটির কোনও সুবিধা রয়েছে যে এটি কোনও বিশ্বব্যাপী রাষ্ট্র পরিবর্তন করে না।
স্মারলিন

32
std::wstring_convertC ++ থেকে এই শব্দ অনেক 11 গোপন।
কুবিবি

7
@ ফিলিপ, আপনার কি অর্থ "উইন্ডোজ সমস্যা তৈরি করবে"? কি ধরনের সমস্যা?
গিলি

1
উপরের কোডটি দেয় (অনুলিপি করা হয়েছে) আমাকে *** glibc detected *** test: malloc(): smallbin double linked list corrupted: 0x000000000180ea30 ***লিনাক্স -৪-বিট (জিসিসি ৪..3.৩) এ দেয়। অন্য কেউ এই অভিজ্ঞতা?
হোগলিক্স

312

যেমন কিউবি একটি মন্তব্যে উল্লেখ করেছেন, std::wstring_convert(সি ++ 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উপরের কোডটি ব্যবহার করছি , তবে আপনি যদি ইউটিএফ -8 ব্যবহার না করেন তবে আপনার সেটি যথাযথ এনকোডিংয়ে ব্যবহার করা উচিত:

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


25
দয়া করে +1 : স্ট্রিং রূপান্তরটি করার এটি সরকারী সি ++ স্ট্যান্ডার্ড উপায়। আপনি অন্য উপায় থেকে রূপান্তর করতে from_bytes ব্যবহার করতে পারেন। যেহেতু আমি ব্যক্তিগতভাবে ওয়ান-লাইনার পছন্দ করি, তা এখানে আমার সংস্করণ:std::wstring str = std::wstring_convert<std::codecvt_utf<wchar_t>>().from_bytes("some string");
গাস

7
দেখে মনে হচ্ছে en + ppreferences.com/w/cpp/header/codecvt g ++ 4.8.2 হিসাবে উপলব্ধ নেই। দুটি s2ws এবং ws2s পদ্ধতি বর্তমানে লিনাক্সের অধীনে কাজ করে না
বেগুই

5
দেখে মনে হচ্ছে এটি অবনমিত ( স্ট্যাকওভারফ্লো . com / a / 42946556 / 211176 )। আমি এই কোডটি চালানোর চেষ্টা করার সময় আমার সংকলক ত্রুটি ছুড়ে
ফেলেছে


5
সি ++ 17 এবং আরও সামঞ্জস্যতা ( অবমূল্যায়নের
টিমো

128

সমাধান থেকে: http://forums.devshed.com/c-programming-42/wstring-to-string-444006.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- একটি সংক্ষিপ্ত রূপান্তর assign এটি স্ট্যান্ড :: স্ট্রিং ক্যাটার ব্যবহার করে :

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

মতামত হিসাবে বলা হয়েছে:

0-127 মানগুলি কার্যত প্রতিটি এনকোডিংয়ে অভিন্ন, সুতরাং মানগুলি ছাঁটাই করা যা সমস্ত পাঠ্য একই পাঠ্যের 127 এর চেয়ে কম হয়। একটি চীনা চরিত্র রাখুন এবং আপনি ব্যর্থতা দেখতে পাবেন।

-

উইন্ডোজ কোডপেজ 1252 (উইন্ডোজ ইংলিশ ডিফল্ট) এর 128-255 এর মান এবং ইউনিকোডের 128-255 এর মানগুলি বেশিরভাগই সমান, তাই যদি আপনি তেমন কোডপেজ ব্যবহার করেন তবে বেশিরভাগ অক্ষরকে সঠিক মানগুলিতে কাটা উচিত। (আমি পুরোপুরি প্রত্যাশা করেছিলাম - এবং work কাজ করবে, আমি জানি যে কাজের ক্ষেত্রে আমাদের কোডগুলি এতে on এর উপর নির্ভর করে, যা আমি শীঘ্রই সংশোধন করব)

এবং মনে রাখবেন সীমার মধ্যে কোড পয়েন্ট অর্জন করে নিজেদের 0x80 - 0x9Fমধ্যে Win1252 হবে না কাজ করি। এর মধ্যে রয়েছে , œ, ž, Ÿ, ...


2
উদ্ভট, এটি ভিজ্যুয়াল স্টুডিও 10 এ কাজ করে? কী চলছে? এটি আসল স্ট্রিংয়ের সমস্ত উপাদানগুলির জন্য wchar_t থেকে চরে একটি কাটা অ্যাসিগমেন্টের কারণ হওয়া উচিত।
পেড্রো লামারো

6
... যখন এটি কোনও ল্যাটিন অক্ষরগুলিতে যায়।
জাভাআরনার

8
@ পেড্রোলেমারো: মানগুলি 0-127 কার্যত প্রতিটি এনকোডিংয়ে অভিন্ন, সুতরাং মানগুলি ছাঁটাই করা যা সমস্ত পাঠ্য একই পাঠ্যর 127 এর চেয়ে কম হয়। একটি চীনা চরিত্র রাখুন এবং আপনি ব্যর্থতা দেখতে পাবেন।
মাকিং হাঁস

3
@ পেড্রোলেমারো: উইন্ডোজ কোডপেজ 1252 (উইন্ডোজ ইংলিশ ডিফল্ট) এর 128-255 এর মান এবং ইউনিকোডের 128-255 এর মানগুলি বেশিরভাগই একই রকম, তাই যদি তেমন কোডেপ ব্যবহার করা হয় তবে আপনি বেশিরভাগ অক্ষরকে সঠিকভাবে কেটে ফেলতে হবে মান। (আমি পুরোপুরি প্রত্যাশা রেখেছিলাম work এবং work কাজ করার জন্য, আমি জানি যে কাজের ক্ষেত্রে আমাদের
কোডগুলি এর

2
এটি দুর্দান্ত কাজ করে। এমএসভিএস 2015 এবং এমএসভিএস 2017 এবং এমিংডাব্লু / জি ++ এবং ঝনঝন ++। আইন ++ 1।
নিকোস

11

লোকেল এবং সমস্ত অভিনব জিনিসগুলি অন্তর্ভুক্ত করার পরিবর্তে, আপনি যদি সত্যের জন্য জানেন তবে আপনার স্ট্রিংটি রূপান্তরযোগ্য এটি কেবল এটি করুন:

#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
নামার0x0309 এর সমাধান হিসাবে প্রায় একই জিনিস, যা অনেক বেশি মার্জিত IMHO। তবে তা কেবল আমিই।
onitake

আমি আপনার কোডটি প্রকৃতপক্ষে ন্যূনতম সংশোধন নিয়ে কাজ করার জন্য তৈরি করেছি ;-)
রুবনেভবি

9
-1 আপনার যদি স্ট্রিং থাকে তবে সম্ভবত আপনি মাল্টিবাইট অক্ষরগুলি নিয়ে কাজ করছেন। যদি আপনি জানতে পারতেন যে স্ট্রিংটি তুচ্ছভাবে রূপান্তরযোগ্য হয় তবে আপনি প্রথম স্থানে কোনও স্ট্রিং পরিচালনা করছেন না। সম্ভবত, আপনি অন্য একটি লাইব্রেরি নিয়ে কাজ করছেন যা আশা করে যে আপনি wstring সঠিকভাবে পরিচালনা করবেন। ওয়াচার্সকে ছাঁটাই করা কেবল পরে বাগটি সনাক্ত করার জন্য শক্ত প্রার্থনা করছে। এছাড়াও, আপনার "স্ট্রিং রেজাল্ট (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;
    }

হ্যাঁ, এটি কাউট এবং ডাব্লুসিআউট ব্যবহার করে সমস্যার সমাধান করে।
BЈовић

7

ডিফল্ট এনকোডিং এতে:

  • উইন্ডোজ ইউটিএফ -16।
  • লিনাক্স ইউটিএফ -8।
  • MacOS UTF-8।

এই কোডটির দুটি রূপ রয়েছে যা std :: স্ট্রিংকে std :: wstring এবং std :: wstring এ std :: স্ট্রিংয়ে রূপান্তর করতে পারে। যদি আপনি #IF সংজ্ঞায়িত WIN32 অস্বীকার করেন তবে আপনি একই ফলাফল পাবেন।

1. স্টাড :: স্ট্রিং থেকে স্টাড :: ডাবল স্ট্রিং

মাল্টিবাইটটওয়েডচার চ্যান উইনাপিআই

_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;
}

২.এসডিডি :: স্ট্রিং থেকে স্ট্রিং :: স্ট্রিং

ওয়াইডচারারটোমল্টিবাট উইনাপিআই

_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;
}

৩. উইন্ডোতে আপনার উইনিকপিআই ব্যবহার করে ইউনিকোড প্রিন্ট করতে হবে।

WritConsole

#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);
    }

৪. মূল প্রোগ্রামে।

#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;
}

৫. অবশেষে কনসোলে ইউনিকোড চরগুলির জন্য আপনার একটি পাওয়ারফুল এবং সম্পূর্ণ সমর্থন প্রয়োজন। আমি কনেমুর পরামর্শ দিচ্ছি এবং উইন্ডোজে ডিফল্ট টার্মিনাল হিসাবে সেট করব । আপনার ভিজুয়াল স্টুডিওটি কনুমুতে আবদ্ধ করতে হবে। মনে রাখবেন ভিজ্যুয়াল স্টুডিওর এক্সি ফাইলটি devenv.exe e

ভিসি ++ সহ ভিজ্যুয়াল স্টুডিও 2017 এ পরীক্ষিত; এসটিডি = C ++ 17।

ফলাফল

Result1


6

আপনি কেবলমাত্র টাইপ ফাইসটির সরু পদ্ধতিটি সরাসরি ব্যবহার করতে পারেন:

# ক্লোকেল> অন্তর্ভুক্ত করুন
# অন্তর্ভুক্ত <লোকাল>
# অন্তর্ভুক্ত <স্ট্রিং>
# অন্তর্ভুক্ত <ভেক্টর>

ইনলাইন স্টাড :: স্ট্রিং সরু
{
    std :: লোকেল কনস্ট লোকেশন ("");
    wchar_t কনস্ট * থেকে = পাঠ্যক্রমে__ (();
    std :: আকার_t কনট লেন = টেক্সট.সাইজ ();
    std :: ভেক্টর <চাপ> বাফার (লেন + 1);
    std :: use_facet <std :: ctype <wchar_t>> (লোকেশন)। ন্যারো (থেকে, + লেন, '_', এবং বাফার [0]);
    ফিরে এসটিডি :: স্ট্রিং (& বাফার [0], এবং বাফার [লেন]);
}

6

এই উত্তরটি লেখার সময়, "রূপান্তরিত স্ট্রিং wstring" এর জন্য এক নম্বর গুগল অনুসন্ধান আপনাকে এই পৃষ্ঠায় নামবে। আমার উত্তরটি দেখায় কিভাবে স্ট্রিংটিকে wstring এ রূপান্তর করা যায়, যদিও এটি আসল প্রশ্ন নয় এবং আমার সম্ভবত এই উত্তরটি মুছতে হবে তবে এটি খারাপ ফর্ম হিসাবে বিবেচিত হয়। আপনি এই স্ট্যাকওভারফ্লো উত্তরটিতে ঝাঁপিয়ে পড়তে চাইতে পারেন , যা এখন এই পৃষ্ঠার চেয়ে উচ্চতর স্থান।


স্ট্রিং, 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
এটি স্ট্রিং রূপান্তরকরণের জন্য কোনও ঝাঁকুনি নয়
পোয়েট্রোয়

1
@ মিশেল আপনি দয়া করে ব্যাখ্যা করতে পারেন? এ সম্পর্কে কী ভুল? আপনার মন্তব্যটি আরও বিশদ ছাড়াই সহায়ক নয়।
নট

1
এটি wstring রূপান্তর একটি স্ট্রিং। অর্থাৎ প্রশ্নের বিপরীত।
জেফ ম্যাকক্লিনটক

4

কেবল ধরণের রূপান্তরিত করার পাশাপাশি, আপনার স্ট্রিংয়ের আসল বিন্যাস সম্পর্কেও সচেতন হওয়া উচিত।

জন্য কম্পাইল মাল্টি বাইট ক্যারেক্টার সেট ভিসুয়াল স্টুডিও এবং উইন এপিআই UTF8 হওয়া অনুমান (আসলে যা এনকোডিং উইন্ডোজ উইন্ডোজ 28591 )।
যখন ইউনিকোড চরিত্র সেট করার জন্য ভিজ্যুয়াল স্টুডিও এবং উইন এপিআই ইউটিএফ 16 ধরে নেয়।

সুতরাং, আপনাকে অবশ্যই স্ট্রিংটি ইউটিএফ 16 থেকে ইউটিএফ 8 ফর্ম্যাটে রূপান্তর করতে হবে, এবং কেবল এসটিডি :: স্ট্রিংয়ে রূপান্তর করতে হবে না।
কিছু নন-ল্যাটিন ভাষার মতো মাল্টি-ক্যারেক্টার ফর্ম্যাটগুলির সাথে কাজ করার সময় এটি প্রয়োজনীয় হয়ে উঠবে।

ধারণাটি স্থির হয় যে std::wstring সর্বদা UTF16 প্রতিনিধিত্ব করে
এবং std::string সর্বদা ইউটিএফ 8 প্রতিনিধিত্ব করে ।

এটি সংকলক দ্বারা প্রয়োগ করা হয়নি, এটির জন্য আরও ভাল নীতি রয়েছে। আমি ইউটিএফ 16 ( এল ) এবং ইউটিএফ 8 ( u8 ) সংজ্ঞায়িত করার জন্য স্ট্রিং উপসর্গগুলি নোট করুন ।

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

আমার ক্ষেত্রে, আমাকে মাল্টিবাইট অক্ষর (এমবিসিএস) ব্যবহার করতে হবে, এবং আমি স্টাডি :: স্ট্রিং এবং এসটিডি :: wstring ব্যবহার করতে চাই। এবং সি ++ 11 ব্যবহার করতে পারবেন না। সুতরাং আমি mbstowcs এবং wcstombs ব্যবহার করি।

আমি নতুন ব্যবহার করে মুছে ফেলা [] মুছে ফেলি, তবে এটি এর চেয়ে ধীর।

এটি কীভাবে: বিভিন্ন স্ট্রিং প্রকারের মধ্যে রূপান্তর করতে সহায়তা করতে পারে

সম্পাদনা

তবে, wstring এবং উত্সের স্ট্রিংয়ে রূপান্তর করার ক্ষেত্রে কোনও বর্ণমালা এবং মাল্টি বাইট স্ট্রিং নয়, এটি কাজ করছে না। সুতরাং আমি wcstombs WideCharToM মাল্টিবাইটে পরিবর্তন করি।

#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);
}

'Wcstombs' এর পরিবর্তে 'মাল্টিবাইটটওয়েডচার' ব্যবহার করতে সম্পাদনা করুন

#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" ব্যবহার করতে পারি? কারণ আমি দেখতে পাচ্ছি যে এটি সি ++ 11 বৈশিষ্ট্য।
ক্রিশ্চিয়ান

@ ক্রিশ্চিয়ান আপনি এই ফাংশনের "অনিরাপদ" সংস্করণটি ব্যবহার করতে পারেন wcstombs()
ভিজোর

3

এই সমাধানটি dk123 এর সমাধানে অনুপ্রাণিত হয়েছে , তবে এটি একটি স্থানীয় নির্ভরশীল কোডেকভেট ফ্যাক্ট ব্যবহার করে। ফলাফলটি ইউটিএফ -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()। আশাকরি এটা সাহায্য করবে.


উদাহরণস্বরূপ, স্থানীয় নির্ভরশীল দিকটি রূপান্তর করার সুবিধা (যদি থাকে) কী কী?
মার্ক ২৩377

আপনি যদি উদাহরণস্বরূপ কনসোল ইনপুট থেকে সিস্টেম থেকে স্ট্রিং নিয়ে কাজ করেন।
ভিজোর

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
ইউটিএফ 8 স্ট্রিং ফাংশনটি কোথা থেকে আসে?
জিন-ক্রিস্টোফ ব্লানচার্ড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.