string
? wstring
?
std::string
একটি হয় basic_string
একটি উপর টেমপ্লেট করা char
, এবং std::wstring
একটি উপর wchar_t
।
char
বনাম wchar_t
char
একটি চরিত্র, সাধারণত একটি 8-বিট চরিত্র ধারণ করার কথা।
wchar_t
ধারণা করা হয় একটি বিস্তৃত চরিত্র রয়েছে, এবং তারপরে, জিনিসগুলি জটিল হয়ে উঠবে:
লিনাক্স-এ, wchar_t
4 বাইট, উইন্ডোতে, এটি 2 বাইট হয়।
সমস্যাটি হ'ল উভয়ই সরাসরি ইউনিকোডের সাথে আবদ্ধ char
নয় wchar_t
।
লিনাক্সে?
একটি লিনাক্স ওএস নেওয়া যাক: আমার উবুন্টু সিস্টেমটি ইতিমধ্যে ইউনিকোড সচেতন। যখন আমি একটি চর স্ট্রিংয়ের সাথে কাজ করি, তখন এটি স্থানীয়ভাবে ইউটিএফ -8 (যেমন অক্ষরের ইউনিকোড স্ট্রিং) এ এনকোড থাকে । নিম্নলিখিত কোড:
#include <cstring>
#include <iostream>
int main(int argc, char* argv[])
{
const char text[] = "olé" ;
std::cout << "sizeof(char) : " << sizeof(char) << std::endl ;
std::cout << "text : " << text << std::endl ;
std::cout << "sizeof(text) : " << sizeof(text) << std::endl ;
std::cout << "strlen(text) : " << strlen(text) << std::endl ;
std::cout << "text(ordinals) :" ;
for(size_t i = 0, iMax = strlen(text); i < iMax; ++i)
{
std::cout << " " << static_cast<unsigned int>(
static_cast<unsigned char>(text[i])
);
}
std::cout << std::endl << std::endl ;
// - - -
const wchar_t wtext[] = L"olé" ;
std::cout << "sizeof(wchar_t) : " << sizeof(wchar_t) << std::endl ;
//std::cout << "wtext : " << wtext << std::endl ; <- error
std::cout << "wtext : UNABLE TO CONVERT NATIVELY." << std::endl ;
std::wcout << L"wtext : " << wtext << std::endl;
std::cout << "sizeof(wtext) : " << sizeof(wtext) << std::endl ;
std::cout << "wcslen(wtext) : " << wcslen(wtext) << std::endl ;
std::cout << "wtext(ordinals) :" ;
for(size_t i = 0, iMax = wcslen(wtext); i < iMax; ++i)
{
std::cout << " " << static_cast<unsigned int>(
static_cast<unsigned short>(wtext[i])
);
}
std::cout << std::endl << std::endl ;
return 0;
}
নিম্নলিখিত পাঠ্য আউটপুট দেয়:
sizeof(char) : 1
text : olé
sizeof(text) : 5
strlen(text) : 4
text(ordinals) : 111 108 195 169
sizeof(wchar_t) : 4
wtext : UNABLE TO CONVERT NATIVELY.
wtext : ol�
sizeof(wtext) : 16
wcslen(wtext) : 3
wtext(ordinals) : 111 108 233
আপনি দেখতে পাবেন "ওল" পাঠ্যটি char
সত্যই চারটি চর দ্বারা নির্মিত: 110, 108, 195 এবং 169 (পিছনের শূন্যটি গণনা করছে না)। (আমি আপনাকে wchar_t
একটি অনুশীলন হিসাবে কোডটি অধ্যয়ন করতে দেব )
সুতরাং, char
লিনাক্সে কোনও কাজ করার সময় , আপনি সাধারণত অজান্তেই ইউনিকোড ব্যবহার করে শেষ হওয়া উচিত। এবং যেমন std::string
কাজ করে char
তেমনি std::string
ইউনিকোড-প্রস্তুত।
নোট করুন std::string
, সি স্ট্রিং এপিআইয়ের মতো, "অল" স্ট্রিংটি তিনটি নয়, 4 টি অক্ষর হিসাবে বিবেচনা করবে। সুতরাং ইউনিকোড অক্ষরের সাথে কাটা / খেলার সময় আপনার সতর্ক হওয়া উচিত কারণ ইউটিএফ -8 এ কিছু অক্ষরের মিশ্রণ নিষিদ্ধ।
উইন্ডোজে?
উইন্ডোজে এটি কিছুটা আলাদা। উইন 32 কে ইউনিকোডের আগমনের আগে, সমস্ত বিশ্বের উত্পাদিত char
বিভিন্ন চরসেট / কোডপেজের সাথে এবং এর সাথে কাজ করার জন্য প্রচুর অ্যাপ্লিকেশন সমর্থন করতে হয়েছিল ।
সুতরাং তাদের সমাধানটি একটি আকর্ষণীয় সমাধান ছিল: যদি কোনও অ্যাপ্লিকেশন এর সাথে কাজ করে char
, তবে মেশিনে স্থানীয় চরসেট / কোডপেজ ব্যবহার করে চার স্ট্রিংগুলি জিইউআই লেবেলে এনকোডড / মুদ্রিত / দেখানো হবে। উদাহরণস্বরূপ, ফরাসি-স্থানীয়করণযুক্ত উইন্ডোতে "ওল" হ'ল "ওল", তবে সিরিলিক-স্থানীয়ীকৃত উইন্ডোজ ("যদি আপনি উইন্ডোজ -1211 ব্যবহার করেন তবে" ওলি ) কিছু আলাদা হবে । সুতরাং, "historicalতিহাসিক অ্যাপ্লিকেশনগুলি" এখনও একই পুরানো পথে কাজ করবে।
ইউনিকোড ভিত্তিক অ্যাপ্লিকেশনগুলির জন্য, উইন্ডোজ ব্যবহার করে wchar_t
, যা 2-বাইট প্রশস্ত, এবং ইউটিএফ -16 এ এনকোড থাকে , যা ইউনিকোড 2-বাইট অক্ষরগুলিতে এনকোড থাকে (বা খুব কমপক্ষে, বেশিরভাগই সুসংগত ইউসিএস -২, যা প্রায় একই জিনিস আইআইআরসি)।
ব্যবহার অ্যাপ্লিকেশন char
বলা হয় "multibyte" (কারণ প্রতিটি গ্লিফের এক বা একাধিক গঠিত হয় char
, গুলি) ব্যবহার করার সময় অ্যাপ্লিকেশন wchar_t
বলা হয় "widechar" (কারণ প্রতিটি গ্লিফের এক বা দুই গঠিত হয় wchar_t
। দেখুন MultiByteToWideChar এবং WideCharToMultiByte আরও তথ্যের জন্য Win32 রূপান্তর API- টি।
সুতরাং, আপনি যদি উইন্ডোজে কাজ করেন তবে আপনি খারাপভাবে ব্যবহার করতে চানwchar_t
(আপনি যদি জিটিকে + বা কিউটি ... এর মতো লুকানো ফ্রেমওয়ার্ক ব্যবহার না করেন )। আসল বিষয়টি হ'ল পর্দার আড়ালে উইন্ডোজ wchar_t
স্ট্রিংয়ের সাথে কাজ করে, তাই এমনকি historicalতিহাসিক অ্যাপ্লিকেশনগুলির এপিআই ব্যবহার করার সময় (উইন 32 জিইউআইতে লেবেল সেট করতে নিম্ন স্তরের এপিআই ফাংশন) তাদের char
স্ট্রিং রূপান্তরিত হবে convertedwchar_t
SetWindowText()
স্মৃতি সমস্যা?
ইউটিএফ -32 অক্ষর প্রতি 4 বাইট, তাই যুক্ত করার মতো খুব বেশি কিছুই নেই, কেবলমাত্র যদি কোনও ইউটিএফ -8 পাঠ্য এবং ইউটিএফ -16 পাঠ্য সর্বদা একটি ইউটিএফ -32 পাঠ্যের চেয়ে কম বা একই পরিমাণ মেমরি ব্যবহার করে (এবং সাধারণত কম )।
যদি কোনও মেমরির সমস্যা থাকে তবে বেশিরভাগ পশ্চিমা ভাষার চেয়ে আপনার জানা উচিত, ইউটিএফ -8 পাঠ্যটি একই ইউটিএফ -১ one এর চেয়ে কম মেমরি ব্যবহার করবে।
তবুও, অন্যান্য ভাষার জন্য (চাইনিজ, জাপানি ইত্যাদি) ব্যবহৃত মেমরিটি ইউটিএফ -8 এর তুলনায় ইউটিএফ -8 এর চেয়ে একরকম বা কিছুটা বড় হবে।
সব মিলিয়ে, ইউটিএফ -16 বেশিরভাগ অক্ষর প্রতি 2 এবং ঘটনাক্রমে 4 বাইট ব্যবহার করবে (যদি না আপনি কোনও রকম রহস্যময় ভাষার গিলিফগুলি (ক্লিংন? এলভিশ?) ব্যবহার করছেন, তবে ইউটিএফ -8 1 থেকে 4 বাইট ব্যয় করবে)।
আরও তথ্যের জন্য http://en.wikedia.org/wiki/UTF-8#Compare_to_UTF-16 দেখুন ।
উপসংহার
যখন আমার স্টাড :: স্ট্রিং ওভার স্ট্রিং :: স্ট্রিং ব্যবহার করা উচিত?
লিনাক্সে? প্রায় না (§).
উইন্ডোজে? প্রায় সবসময় (§).
ক্রস প্ল্যাটফর্ম কোডে? আপনার টুলকিট উপর নির্ভর করে ...
(§): আপনি অন্যথায় বলার মতো কোনও সরঞ্জামকিট / ফ্রেমওয়ার্ক ব্যবহার না করে
std::string
বিশেষ অক্ষর সহ সমস্ত ASCII চরিত্র সেটটি ধরে রাখতে পারে?
বিজ্ঞপ্তি: std::string
একটি 'বাইনারি' বাফার ধরে রাখার জন্য উপযুক্ত, যেখানে একটি std::wstring
নেই!
লিনাক্সে? হ্যাঁ.
উইন্ডোজে? উইন্ডোজ ব্যবহারকারীর বর্তমান লোকেলের জন্য কেবলমাত্র বিশেষ অক্ষর উপলব্ধ।
সম্পাদনা ( জোহান জেরেলের একটি মন্তব্যের পরে ):
একটি std::string
সমস্ত- char
ভিত্তিক স্ট্রিংগুলি হ্যান্ডেল করার জন্য যথেষ্ট হবে (প্রত্যেকটি char
0 থেকে 255 পর্যন্ত একটি সংখ্যা)। কিন্তু:
- ASCII 0 থেকে 127 যাওয়ার কথা
char
রয়েছে। উচ্চতরগুলি ASCII নয়।
char
0 থেকে 127 পর্যন্ত একটি সঠিকভাবে অনুষ্ঠিত হবে
- একটি
char
128 থেকে 255 আপনার এনকোডিং (ইউনিকোড, অ-ইউনিকোড, ইত্যাদি) উপর নির্ভর করে একটি গুরূত্ব থাকবে, কিন্তু এটা হিসাবে তারা হল UTF-8 এনকোড করা হয় যতদিন সব ইউনিকোড গ্লিফ রাখা সক্ষম হবে।
হয় std::wstring
প্রায় সব জনপ্রিয় সি ++ কম্পাইলার দ্বারা সমর্থিত?
বেশিরভাগ ক্ষেত্রে, উইন্ডোতে পোর্ট করা জিসিসি ভিত্তিক সংকলক ব্যতীত।
এটি আমার জি ++ ৪.৩.২ (লিনাক্সের অধীনে) কাজ করে এবং আমি ভিজ্যুয়াল সি ++ 6 সাল থেকে উইন 32 এ ইউনিকোড এপিআই ব্যবহার করেছি।
বিস্তৃত চরিত্রটি আসলে কী?
সি / সি ++ এ, এটি একটি অক্ষর টাইপ লিখিত wchar_t
যা সাধারণ char
অক্ষরের ধরণের চেয়ে বড় is এটি এমন অক্ষরের ভিতরে রাখতে ব্যবহার করা হবে যার সূচিগুলি (ইউনিকোড গ্লাইফগুলি) 255 (বা 127, নির্ভর করে ...) এর চেয়ে বড়।