সি ++ স্ট্রিং (বা চর *) কে স্ট্রিংয়ে রূপান্তর করুন (বা wchar_t *)


171
string s = "おはよう";
wstring ws = FUNCTION(s, ws);

আমি কীভাবে s এর সামগ্রীগুলি ডাব্লুএসকে অর্পণ করব?

গুগল অনুসন্ধান করেছেন এবং কিছু কৌশল ব্যবহার করেছেন তবে তারা সঠিক সামগ্রী নির্ধারণ করতে পারে না। বিষয়বস্তু বিকৃত হয়।


7
আমি strings> 8-বিট অক্ষর গ্রহণ করে বলে মনে করি না । এটি ইতিমধ্যে ইউটিএফ -8 এ এনকোড করা আছে?
কেনেটিএম

3
আপনার সিস্টেমটি এনকোডিং কী এমন এটি "おはよう"সিস্টেম-এনকোডযুক্ত স্ট্রিং তৈরি করবে?
এসবিআই

আমি বিশ্বাস করি এমএসভিসি এটি গ্রহণ করবে এবং এটিকে কিছু মাল্টিবাইট এনকোডিং তৈরি করবে, সম্ভবত ইউটিএফ -8 করবে।
পোটোটোওয়াতর

1
@ পোটাটোসওয়াতর: এমএসভিসি ইউটিএফ -8 ব্যবহারের জন্য ডিফল্টরূপে কিছু নয়। আপনি ঐ অক্ষর লিখুন, এটা যা ফাইল রূপান্তর করতে এনকোডিং জিজ্ঞেস করে, এবং codepage 1252. ডিফল্ট
গরুর হাঁসের

2
@ সমীর: আরও গুরুত্বপূর্ণ ফাইলটির এনকোডিং কী ? আপনি কি সেই স্ট্রিংটি ফাইলের শুরুতে নিয়ে যেতে এবং সেই অংশটির একটি হেক্সডাম্প প্রদর্শন করতে পারেন? আমরা সম্ভবত এটি থেকে সনাক্ত করতে পারি।
মাকিং হাঁস

উত্তর:


239

ধরে নিই যে আপনার উদাহরণের ইনপুট স্ট্রিং (お は よ う) হ'ল একটি ইউটিএফ -8 এনকোডযুক্ত (এটি এটির দ্বারা দেখা যাচ্ছে না, তবে ধরা যাক এটি এই ব্যাখ্যাটির জন্য :-)) ইউনিকোড স্ট্রিংয়ের উপস্থাপনা আপনার আগ্রহের বিষয়, তবে আপনার সমস্যাটি সম্পূর্ণ একা স্ট্যান্ডার্ড লাইব্রেরি (সি ++ 11 এবং আরও নতুন) দিয়ে সমাধান করা যেতে পারে।

টিএল; ডিআর সংস্করণ:

#include <locale>
#include <codecvt>
#include <string>

std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::string narrow = converter.to_bytes(wide_utf16_source_string);
std::wstring wide = converter.from_bytes(narrow_utf8_source_string);

দীর্ঘ অনলাইন সংকলনযোগ্য এবং চলমান উদাহরণ:

(তারা সকলেই একই উদাহরণ দেখায় red অতিরিক্ত অর্থহীনতার জন্য অনেকগুলি রয়েছে ...)

দ্রষ্টব্য (পুরানো) :

মতামতগুলিতে নির্দেশিত এবং https://stackoverflow.com/a/17106065/6345-তে ব্যাখ্যা করা হয়েছে যে ইউটিএফ -8 এবং ইউটিএফ -16 এর মধ্যে রূপান্তর করতে স্ট্যান্ডার্ড লাইব্রেরি ব্যবহার করার সময় বিভিন্ন প্ল্যাটফর্মের ফলাফলগুলিতে অপ্রত্যাশিত পার্থক্য হতে পারে । আরও ভাল রূপান্তরকরণের জন্য, http://en.cppreferences.com/w/cpp/locale/codecvt_utf8 এstd::codecvt_utf8 বর্ণিত হিসাবে বিবেচনা করুন

দ্রষ্টব্য (নতুন) :

যেহেতু codecvtশিরোনামটি সি ++ 17 এ অবমানিত হয়েছে তাই এই উত্তরে উপস্থাপিত সমাধান সম্পর্কে কিছুটা উদ্বেগ উত্থাপিত হয়েছিল। যাইহোক, সি ++ স্ট্যান্ডার্ড কমিটিতে গুরুত্বপূর্ণ বিবৃতি যোগ http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0618r0.html বলার অপেক্ষা রাখে না

একটি উপযুক্ত প্রতিস্থাপন মানক না করা অবধি এই লাইব্রেরির উপাদানটি অ্যাঙ্কেক্স ডিতে অবসর নেওয়া উচিত।

সুতরাং অদূর ভবিষ্যতে, codecvtএই উত্তরের সমাধানটি নিরাপদ এবং পোর্টেবল।


2
আপনি কোন এনকোডিংয়ের সাথে ভিএস ফাইলগুলি সংরক্ষণ করছেন তা যাচাই করুন
জোহান জেরেল

9
সচেতন থাকুন যে এটি কেবল সি ++ 11 -ই!
বিকে 138

1
MinGW (gcc / g ++ 4.8.1 এবং -std = c ++ 11) এ কোডেকটি শিরোনামের অস্তিত্ব নেই। বিকল্প আছে?
ব্রায়ান জ্যাক

1
আপনি দয়া করে std::codecvt_utf8নতুনদের জন্য উদাহরণ সরবরাহ করতে পারেন
নোটিডার্ট

14
দয়া করে নোট করুন যে <codecvt>C ++ 17 এর পরে অবনতিযুক্ত।
tamre

47
int StringToWString(std::wstring &ws, const std::string &s)
{
    std::wstring wsTmp(s.begin(), s.end());

    ws = wsTmp;

    return 0;
}

93
এটি কেবলমাত্র যদি সমস্ত অক্ষর একক বাইট হয়, যেমন ASCII বা আইএসও -8859-1 হয় তবে এটি কাজ করে । মাল্টি-বাইটের যে কোনও কিছুই ইউটিএফ -8 সহ, খারাপভাবে ব্যর্থ হবে। প্রশ্নটিতে পরিষ্কারভাবে মাল্টি-বাইট অক্ষর রয়েছে।
মার্ক মুক্তি পেতে

28
এই উত্তরটি পরিষ্কারভাবে অপর্যাপ্ত এবং বিস্তৃত অক্ষরের মতো সংকীর্ণ অক্ষরগুলি অনুলিপি করা ছাড়া কিছুই করে না। মাল্টি বাইট বা ইউটিএফ 8 এনকোডযুক্ত স্ট্রিং থেকে কোনও ইউটিএফ 16 ওয়াস্ট্রিংয়ে কীভাবে যেতে হবে তার জন্য অন্যান্য উত্তরগুলি দেখুন, বিশেষত জোহান জেরেলের একটি।
ডিএলআরডেভ

10
এই উত্তরটি বিপজ্জনক এবং সম্ভবত অ-এসিআই সিস্টেমে ভেঙে যাবে। অর্থাত্ একটি আরবিক ফাইলের নাম এই হ্যাকটি দ্বারা ম্যাঙ্গেল হয়ে যাবে।
স্টিফেন

9
যদি আপনি প্রশ্নের শরীরের সংক্ষিপ্ততা উপেক্ষা করেন এবং প্রশ্নের শিরোনামের দিকে মনোনিবেশ করেন তবে এই উত্তরটি দরকারী যা আমাকে এখানে গুগল থেকে এনেছে। যেমনটি, প্রশ্নের শিরোনামটি অত্যন্ত বিভ্রান্তিমূলক এবং জিজ্ঞাসিত সত্য প্রশ্নের প্রতিফলিত করার জন্য এটি পরিবর্তন করা উচিত
আন কুইন

3
এটি শুধুমাত্র 7-বিট ASCII অক্ষরের জন্য কাজ করে। লাতিন 1 এর জন্য, এটি কেবল তখনই কাজ করে যদি চর স্বাক্ষরযুক্ত হিসাবে কনফিগার করা থাকে। টাইপ চরটি স্বাক্ষরিত হলে (যা বেশিরভাগ ক্ষেত্রে ক্ষেত্রে হয়), অক্ষর> 127 ভুল ফলাফল দেয়।
হাইচ

32

আপনার প্রশ্ন অপ্রকাশিত কঠোরভাবে, উদাহরণটি একটি সিনট্যাক্স ত্রুটি। তবে, std::mbstowcsসম্ভবত আপনি যা খুঁজছেন

এটি একটি সি-লাইব্রেরি ফাংশন এবং বাফারগুলিতে পরিচালিত হয়, তবে এখানে টিবি বোহেন (পূর্বে মুইং হাঁস) এর সৌজন্যে সহজেই ব্যবহারযোগ্য আইডিয়াম:

std::wstring ws(s.size(), L' '); // Overestimate number of code points.
ws.resize(std::mbstowcs(&ws[0], s.c_str(), s.size())); // Shrink to fit.

1
স্ট্রিং s = "お は よ う"; wchar_t * buf = new wchar_t [s.size ()]; আকার_t num_chars = mbstowcs (বুফ, এস সি__সেট্র (), এস.সাইজ ()); wstring ws (বুফ, নাম_চার্স); // ডাব্লুএস = বিকৃত
সমির

1
@ সমীর: আপনাকে নিশ্চিত করতে হবে যে রানটাইম এনকোডিংটি সংকলন-সময় এনকোডিংয়ের সমান। setlocaleসংকলক পতাকাগুলি আপনার প্রয়োজন হতে পারে বা সামঞ্জস্য করতে পারে । আমি জানিনা কারণ আমি উইন্ডোজ ব্যবহার করি না, তবে এটি সাধারণ বৈশিষ্ট্য নয়। সম্ভব হলে অন্য উত্তরটি বিবেচনা করুন।
পোটোটোওয়টার

1
std::string ws(s.size()); ws.resize(mbstowcs(&ws[0], s.c_str(), s.size());RAII FTW
মাকিং হাঁস

2
@ ওয়াফলসফল এটি পুরানো। ২০১১ সাল থেকে অবিচ্ছিন্ন বাস্তবায়ন প্রয়োজন এবং বাস্তবায়নগুলি এর অনেক আগে এরকম কৌশল অবলম্বন করে।
পোটোসওয়টার

1
এবং মিংডব্লির মতো কিছু পরিবেশের এখনও কোডেকটি শিরোনাম নেই তাই বেশিরভাগ 'ভাল' সমাধানগুলি কাজ করে না এর অর্থ এই সমস্যাটির এখনও মাইংডে তেমন কোনও ভাল সমাধান নেই 2014 সালের ডিসেম্বর পর্যন্ত
ব্রায়ান জ্যাক

18

উইন্ডোজ এপিআই, কেবল সি ++ 11 বাস্তবায়ন পূর্বের ক্ষেত্রে কারওর প্রয়োজন হলে:

#include <stdexcept>
#include <vector>
#include <windows.h>

using std::runtime_error;
using std::string;
using std::vector;
using std::wstring;

wstring utf8toUtf16(const string & str)
{
   if (str.empty())
      return wstring();

   size_t charsNeeded = ::MultiByteToWideChar(CP_UTF8, 0, 
      str.data(), (int)str.size(), NULL, 0);
   if (charsNeeded == 0)
      throw runtime_error("Failed converting UTF-8 string to UTF-16");

   vector<wchar_t> buffer(charsNeeded);
   int charsConverted = ::MultiByteToWideChar(CP_UTF8, 0, 
      str.data(), (int)str.size(), &buffer[0], buffer.size());
   if (charsConverted == 0)
      throw runtime_error("Failed converting UTF-8 string to UTF-16");

   return wstring(&buffer[0], charsConverted);
}

আপনি এটি অপ্টিমাইজ করতে পারেন। এ ব্যবহার করে স্ট্রিংয়ের ডাবল কপি করার দরকার নেই vector। কেবলমাত্র করে স্ট্রিং অক্ষর রিজার্ভ wstring strW(charsNeeded + 1);এবং তারপর রূপান্তর জন্য বাফার হিসাবে এটি ব্যবহার: &strW[0]। শেষ পর্যন্ত নিশ্চিত করুন যে শেষ strW[charsNeeded] = 0;
নালটি

1
@ c00000fd, যতদূর আমি জানি, স্ট্যান্ড :: মৌলিক_ স্ট্রিং অভ্যন্তরীণ বাফারটি কেবলমাত্র সি ++ 11 স্ট্যান্ডার্ডের কারণে অবিচ্ছিন্ন হওয়া প্রয়োজন। আমার কোডটি পূর্বের সি ++ 11, পোস্টের শীর্ষে উল্লিখিত হয়েছে। অতএব, & strW [0] কোডটি মান সম্মত হবে না এবং রানটাইমের সময় বৈধভাবে ক্র্যাশ হতে পারে।
অ্যালেক্স চে

13

আপনি যদি উইন্ডোজ / ভিজ্যুয়াল স্টুডিও ব্যবহার করেন এবং স্ট্রিংকে উইস্ট্রিংয়ে রূপান্তর করতে প্রয়োজন হয় আপনি ব্যবহার করতে পারেন:

#include <AtlBase.h>
#include <atlconv.h>
...
string s = "some string";
CA2W ca2w(s.c_str());
wstring w = ca2w;
printf("%s = %ls", s.c_str(), w.c_str());

স্ট্রিং করার জন্য একটি wstring রূপান্তরের জন্য একই পদ্ধতি (কখনও কখনও আপনি একটি নির্দিষ্ট করার প্রয়োজন হবে codepage ):

#include <AtlBase.h>
#include <atlconv.h>
...
wstring w = L"some wstring";
CW2A cw2a(w.c_str());
string s = cw2a;
printf("%s = %ls", s.c_str(), w.c_str());

আপনি একটি কোডপেজ এবং এমনকি ইউটিএফ 8 নির্দিষ্ট করতে পারেন (এটি জেএনআই / জাভার সাথে কাজ করার সময় খুব সুন্দর )। একটি স্ট্যান্ডার্ড :: ডাব্লু স্ট্রিংকে utf8 স্টাড :: স্ট্রিংয়ে রূপান্তর করার একটি মানক উপায় এই উত্তরে দেখানো হয়েছে

// 
// using ATL
CA2W ca2w(str, CP_UTF8);

// 
// or the standard way taken from the answer above
#include <codecvt>
#include <string>

// convert UTF-8 string to wstring
std::wstring utf8_to_wstring (const std::string& str) {
    std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
    return myconv.from_bytes(str);
}

// convert wstring to UTF-8 string
std::string wstring_to_utf8 (const std::wstring& str) {
    std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
    return myconv.to_bytes(str);
}

আপনি কোডেপেজ সম্পর্কে আরও জানতে চাইলে সফটওয়্যারের উপর জোয়েলের একটি আকর্ষণীয় নিবন্ধ রয়েছে: পরম নূন্যতম প্রতিটি সফ্টওয়্যার বিকাশকারী অবশ্যই, ইউনিকোড এবং চরিত্রের বিভাগ সম্পর্কে ইতিবাচকভাবে অবশ্যই জানতে হবে

এই CA2W (রূপান্তর আনসি থেকে চওড়া = ইউনিকোড) ম্যাক্রোগুলি এটিএল এবং এমএফসি স্ট্রিং রূপান্তর ম্যাক্রোর অংশ , নমুনাগুলি অন্তর্ভুক্ত।

কখনও কখনও আপনাকে সুরক্ষা সতর্কতা # 4995 'অক্ষম করতে হবে, আমি অন্য কাজের কথা জানি না (যখন আমি ভিএস ২০১২-তে উইন্ডোজএক্সপি-র জন্য সংকলন করেছি তখন আমার ক্ষেত্রে এটি ঘটে)।

#pragma warning(push)
#pragma warning(disable: 4995)
#include <AtlBase.h>
#include <atlconv.h>
#pragma warning(pop)

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


দুঃখিত আমি নেটিভ ইংরেজি স্পিকার নই। আপনি উপযুক্ত হিসাবে দেখুন সম্পাদনা করুন।
lmiguelmh

ডাউনওয়টারের কী অবস্থা? উত্তরে ভুল কী?
lmiguelmh

সম্ভবত এটি নন-পোর্টেবল কোডটি প্রচার করে।
পাভেল মিনায়েভ

হ্যাঁ, এজন্যই আমি বলেছি যে এটি কেবল উইন্ডোজ / ভিজ্যুয়াল স্টুডিওতে কাজ করে। তবে কমপক্ষে এই সমাধানটি সঠিক, এবং char* str = "hello worlddd"; wstring wstr (str, str+strlen(str));
এটির

অতিরিক্ত দ্রষ্টব্য: CA2W এটিএল এর নেমস্পেসের অধীনে। (ATL :: CA2W)
Val,

12

এখানে মিশ্রন করার জন্য একটি উপায় আছে string, wstringএবং মিশ্র স্ট্রিং ধ্রুবক wstringwstringstreamক্লাস ব্যবহার করুন ।

এটি মাল্টি-বাইট অক্ষর এনকোডিংয়ের জন্য কাজ করে না। এটি প্রকারের সুরক্ষা ফেলে দেওয়া এবং স্টাড :: স্ট্রিং থেকে স্ট্যান্ড: ডাব্লু স্ট্রিংয়ের প্রতিটি অক্ষরের নিম্ন 7 বিটগুলিতে 7 বিট অক্ষর প্রসারিত করার এক মূক উপায় way এটি কেবল তখনই কার্যকর যখন আপনার কাছে 7-বিট ASCII স্ট্রিং রয়েছে এবং আপনার এমন একটি API কল করতে হবে যাতে প্রশস্ত স্ট্রিং দরকার।

#include <sstream>

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

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

উত্তরটি আকর্ষণীয় বলে মনে হচ্ছে। আপনি দয়া করে কিছুটা ব্যাখ্যা করতে পারেন: এটি কি বহু-বাইট এনকোডিংগুলির জন্য কাজ করবে এবং কেন / কীভাবে?
WH1t3cat1k

এনকোডিং প্রকল্পগুলি স্টোরেজ শ্রেণীর জন্য অরথোগোনাল। string1 বাইট অক্ষর এবং wstring2 বাইট অক্ষর সঞ্চয় করে। utf8 এর মতো কিছু 1 বাইট মানগুলির সিরিজ হিসাবে mulitbyte অক্ষর সংরক্ষণ করে, যেমন একটিতে string। স্ট্রিং ক্লাসগুলি এনকোডিংয়ে সহায়তা করে না। আমি সি ++ তে এনকোডিং ক্লাসে বিশেষজ্ঞ নই।
Lakata

2
এটি যেহেতু সংক্ষিপ্ত এবং সহজ এটি দেওয়া কেন এটি উত্তম উত্তর না হওয়ার কোনও কারণ? এটি কোন মামলার আওতায় আসে না?
রিউইউ

@ মার্কলকাতা, আমি প্রথম মন্তব্যে আপনার উত্তরটি পড়েছি তবে এখনও নিশ্চিত নই। এটি কি বহু-বাইট অক্ষরের জন্য কাজ করবে? অন্য কথায়, এটি কি এই উত্তরটির মতো একই সমস্যার জন্য প্রবণ নয় ?
মার্ক ২৩377

@ মার্ক ২৩377 এটি মাল্টি-বাইট চরিত্রের এনকোডিংয়ের জন্য কাজ করে না। এটি প্রকারের সুরক্ষা দূরে ফেলে দেওয়া std::stringএবং প্রতিটি অক্ষরের নীচে 7 বিটের মধ্যে 7 বিট অক্ষর বিস্তৃত করার এক মূক উপায় std:wstring। এটি কেবল তখনই কার্যকর যখন আপনার কাছে 7-বিট ASCII স্ট্রিং রয়েছে এবং আপনার এমন একটি API কল করতে হবে যাতে প্রশস্ত স্ট্রিং দরকার। আপনার যদি আরও পরিশীলিত কিছু প্রয়োজন হয় তবে স্ট্যাকওভারফ্লো . com/a/8969776/3258851 দেখুন।
Lakata

11

থেকে char*থেকে wstring:

char* str = "hello worlddd";
wstring wstr (str, str+strlen(str));

থেকে stringথেকে wstring:

string str = "hello worlddd";
wstring wstr (str.begin(), str.end());

নোটটি রূপান্তরিত হচ্ছে কেবলমাত্র ASCII অক্ষর যুক্ত থাকলে এটি কেবলমাত্র কাজ করে নোট করুন।


7
কারণ এটি কেবল তখনই কাজ করে যদি এনকোডিংটি উইন্ডোজ -১২২২ হয়, যা এমনকি প্রশ্নের অক্ষরগুলি ধরে রাখতে পারে না।
মাকিং হাঁস

3
এটি ASCII এর সাথে লেনদেন করার সময় এটি করা সবচেয়ে কম ত্রুটিযুক্ত প্রবণতা। নতুন এপিআই-তে অ্যাপ্লিকেশনগুলি বন্টন করার সময় যা বিশিষ্ট ইউসকেস।
সিড সরস্বতী

এই উপায় না । আপনি যদি ভিজ্যুয়াল স্টুডিও ব্যবহার করছেন তবে আপনার ব্যবহার করা উচিত atlconv.h। অন্যান্য উত্তরগুলি পরীক্ষা করুন।
lmiguelmh

7

বুস্ট.লোকেল ব্যবহার করে:

ws = boost::locale::conv::utf_to_utf<wchar_t>(s);

5

এর এই রূপটি বাস্তব জীবনে আমার প্রিয়। এটি যদি ইনপুটটিকে বৈধ ইউটিএফ -8 হয় তবে তা সংশ্লিষ্টদের কাছে রূপান্তর করে wstring। যদি ইনপুটটি দূষিত wstringহয় তবে একক বাইটগুলির বাইরে তৈরি করা হয়। আপনি যদি আপনার ইনপুট ডেটার গুণমান সম্পর্কে সত্যতা নিশ্চিত না করতে পারেন তবে এটি অত্যন্ত সহায়ক।

std::wstring convert(const std::string& input)
{
    try
    {
        std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
        return converter.from_bytes(input);
    }
    catch(std::range_error& e)
    {
        size_t length = input.length();
        std::wstring result;
        result.reserve(length);
        for(size_t i = 0; i < length; i++)
        {
            result.push_back(input[i] & 0xFF);
        }
        return result;
    }
}

1
আমি শুধু এই প্রশ্নের আপনার উত্তরের উপর ভিত্তি করে চালু stackoverflow.com/questions/49669048/... আপনি কল্যাণকামী দেখে নিতে পারেন
MistyD

2

আপনার যদি QT থাকে এবং যদি আপনি কোনও ফাংশন এবং স্টাফ প্রয়োগ করতে অলস হন তবে আপনি ব্যবহার করতে পারেন

std :: স্ট্রিং str; QString (STR) .toStdWString ()


প্রায়, তবে আপনার কেবল একটি দিয়ে শুরু করা উচিত QString, কারণ QStringকনস্ট্রাক্টর কোনও কারণে স্ট্রিং গ্রহণ করতে পারে না।
bobsbeenjamin


এটা সুন্দর. এছাড়াও, আপনি কিউ স্ট্রিংকে কনস্ট্রাক্টরে আপনার স্ট্রিং গ্রহণ করতে দিতে .c_str () ব্যবহার করতে পারেন ।
miep

1

পদ্ধতি s2ws ভাল কাজ করে। আশা সাহায্য করে।

std::wstring s2ws(const std::string& s) {
    std::string curLocale = setlocale(LC_ALL, ""); 
    const char* _Source = s.c_str();
    size_t _Dsize = mbstowcs(NULL, _Source, 0) + 1;
    wchar_t *_Dest = new wchar_t[_Dsize];
    wmemset(_Dest, 0, _Dsize);
    mbstowcs(_Dest,_Source,_Dsize);
    std::wstring result = _Dest;
    delete []_Dest;
    setlocale(LC_ALL, curLocale.c_str());
    return result;
}

6
এই সমস্ত উত্তরগুলির একটি কী অনিরাপদ উপায়ে গতিশীল মেমরি বরাদ্দ করে, এবং তারপরে বাফার থেকে স্ট্রিংয়ে ডেটা অনুলিপি করে? কেন কেউ অনিরাপদ মধ্যস্থতাকারী থেকে মুক্তি পাবে না?
মাকিং হাঁস

hahakubile, আপনি কি ws2s এর অনুরূপ কিছু দিয়ে সাহায্য করতে পারেন?
ক্রিশ্চিয়ান

1

আমার নিজের পরীক্ষার উপর ভিত্তি করে (উইন্ডোজ 8, বনাম 2010 তে) এমবিস্টোक्स আসলে আসল স্ট্রিংটিকে ক্ষতি করতে পারে, এটি কেবল এএনএসআই কোড পৃষ্ঠাতে কাজ করে। যদি মাল্টিবাইটটিওয়েডচার / ওয়াইডচার্টটোমলটিবাইটিও স্ট্রিং দুর্নীতির কারণ হতে পারে - তবে তারা এমন অক্ষরগুলিকে প্রতিস্থাপন করতে ঝোঁকায় যা তারা জানে না? ' প্রশ্ন চিহ্নগুলি, তবে এমবিস্টভ্যাকস যখন অজানা চরিত্রের মুখোমুখি হয় এবং স্ট্রিংটি কাটিয়ে দেয় তখন থামতে থাকে। (আমি ফিনিশ উইন্ডোতে ভিয়েতনামি চরিত্রগুলি পরীক্ষা করেছি)।

সুতরাং এনালগ আনসি সি ফাংশনের চেয়ে বহু * উইন্ডোজ এপিআই ফাংশনটি পছন্দ করুন।

এছাড়াও আমি একটি কোডপেজ থেকে অন্যটিতে স্ট্রিং এনকোড করার সবচেয়ে সংক্ষিপ্ততম উপায়টি মাল্টিবাইটটিওয়েডচারার / ওয়াইডচারারটোমল্টিবাটি এপিআই ফাংশন কলগুলি ব্যবহার করি না তবে তাদের অ্যানালগ এটিএল ম্যাক্রোগুলি: W2A / A2W।

উপরে উল্লিখিত এনালগ ফাংশনটি শোনাবে:

wstring utf8toUtf16(const string & str)
{
   USES_CONVERSION;
   _acp = CP_UTF8;
   return A2W( str.c_str() );
}

_acp USES_CONVERSION ম্যাক্রোতে ঘোষিত হয়েছে।

বা পুরানো ডেটা রূপান্তর করার সময় নতুনটিতে রূপান্তর করার সময় আমি প্রায়শই মিস করি যা ফাংশন:

string ansi2utf8( const string& s )
{
   USES_CONVERSION;
   _acp = CP_ACP;
   wchar_t* pw = A2W( s.c_str() );

   _acp = CP_UTF8;
   return W2A( pw );
}

তবে দয়া করে লক্ষ্য করুন যে সেই ম্যাক্রোর ব্যবহারগুলি প্রচুর পরিমাণে স্ট্যাক - একই ফাংশনের জন্য লুপ বা পুনরাবৃত্ত লুপগুলির জন্য ব্যবহার করবেন না - ডাব্লু 2 এ বা এ 2 ডাব্লু ম্যাক্রো ব্যবহারের পরে - এএসএপি ফেরত ভাল, সুতরাং স্ট্যাকটি অস্থায়ী রূপান্তর থেকে মুক্তি পাবে।


1

স্ট্রিং wstring

std::wstring Str2Wstr(const std::string& str)
{
    int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
    std::wstring wstrTo(size_needed, 0);
    MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
    return wstrTo;
}

স্ট্রিং থেকে wstring

std::string Wstr2Str(const std::wstring& wstr)
{
    typedef std::codecvt_utf8<wchar_t> convert_typeX;
    std::wstring_convert<convert_typeX, wchar_t> converterX;
    return converterX.to_bytes(wstr);
}

1
এই Str2Wstr 0 টি সমাপ্তির সাথে একটি সমস্যা আছে। "+" (Wstring s3 = s1 + s2 এর মতো) এর মাধ্যমে আর জেনারেট করা রস্ট্রিংগুলিকে সংযুক্ত করা সম্ভব নয়। এই সমস্যাটি সমাধান করার জন্য আমি শীঘ্রই একটি উত্তর পোস্ট করব। প্রথমে মেমরি ফাঁসের জন্য কিছু পরীক্ষা করতে হবে।
হোয়াইটামবিত

-2

string s = "おはよう"; একটি ত্রুটি।

আপনার সরাসরি wstring ব্যবহার করা উচিত:

wstring ws = L"おはよう";

1
এটিও কাজ করে না। আপনাকে those নন-বিএমপি অক্ষরগুলি সি এস্কেপ সিকোয়েন্সগুলিতে রূপান্তর করতে হবে।
ডেভ ভ্যান ডেন আইন্দে

3
@ ডেভ: আপনার সংকলক যদি উত্স ফাইলগুলিতে ইউনিকোড সমর্থন করে, এবং শেষ দশকের সমস্তগুলি (ভিজ্যুয়াল স্টুডিও, জিসিসি, ...)
থমাস বোনি এই

হাই, ডিফল্ট সিস্টেম এনকোডিং নির্বিশেষে (আমার ডিফল্ট সিস্টেম এনকোডিং হিসাবে আরবি থাকতে পারে) উদাহরণস্বরূপ, L "は は よ う" কাজ করার জন্য উত্স কোড ফাইলটির এনকোডিংটি কী করা উচিত? এটি ইউটিএফ -16 এ থাকা উচিত বা আমার কাছে .cpp ফাইল এনকোডিংয়ের জন্য বিওএম ছাড়াই ইউটিএফ -8 থাকতে পারে?
আফ্রিজা এন আরিফ

2
@ আফ্রিজা: যতক্ষণ না আপনার সংকলনটি সমর্থন করে ততক্ষণ তা সত্যিকার অর্থে আসে না
টমাস বোনিিনি

2
এটি ত্রুটি নয়; "সংকীর্ণ" স্ট্রিংয়ের প্রসারিত অক্ষরগুলি মাল্টিবাইট সিকোয়েন্সগুলিতে মানচিত্রের জন্য সংজ্ঞায়িত করা হয়। সংকলকটির যতক্ষণ না ওএস কাজ করে ততক্ষণ এটি সমর্থন করা উচিত, যা আপনি সবচেয়ে কম জিজ্ঞাসা করতে পারেন।
পোটোসওয়টার

-2

আপনার স্ট্রিংটিকে wstring এ রূপান্তর করতে এই কোডটি ব্যবহার করুন

std::wstring string2wString(const std::string& s){
    int len;
    int slength = (int)s.length() + 1;
    len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); 
    wchar_t* buf = new wchar_t[len];
    MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
    std::wstring r(buf);
    delete[] buf;
    return r;
}

int main(){
    std::wstring str="your string";
    std::wstring wStr=string2wString(str);
    return 0;
}

3
নোট করুন যে প্রশ্নের উইন্ডোজটির কোনও উল্লেখ নেই এবং এই উত্তরটি উইন্ডোজ-কেবল is
জোহান জেরেল

CP_ACPখুব অবশ্যই ভুল যুক্তি। হঠাৎ করেই, এক্সিকিউটিভ থ্রেডের পরিবেশের স্থিতি কোডের আচরণে প্রভাব ফেলে। পরামর্শ দেওয়া হয় না। আপনার রূপান্তরটিতে একটি নির্দিষ্ট অক্ষর এনকোডিং নির্দিষ্ট করুন। (এবং হ্যান্ডলিং ত্রুটিগুলি বিবেচনা করুন))
IInspectable
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.