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
सीधे यूनिकोड से जुड़ा हुआ है।
लिनक्स पर?
चलो एक लिनक्स ओएस लेते हैं: मेरा उबंटू सिस्टम पहले से ही यूनिकोड जागरूक है। जब मैं चार स्ट्रिंग के साथ काम करता हूं, तो यह मूल रूप से UTF-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
आप देखेंगे कि "olé" पाठ char
वास्तव में चार वर्णों द्वारा निर्मित है: 110, 108, 195 और 169 (अनुगामी शून्य की गिनती नहीं)। (मैं आपको wchar_t
अभ्यास के रूप में कोड का अध्ययन करने दूंगा )
इसलिए, जब char
लिनक्स पर काम करते हैं , तो आपको आमतौर पर यूनिकोड का उपयोग किए बिना इसे समाप्त करना चाहिए। और जैसा कि std::string
काम करता है char
, इसलिए std::string
पहले से ही यूनिकोड तैयार है।
ध्यान दें कि std::string
, सी स्ट्रिंग एपीआई की तरह, "ओले" स्ट्रिंग पर विचार करने के लिए 4 वर्ण होंगे, तीन नहीं। इसलिए यूनिकोड वर्णों के साथ छंटनी / खेलने के दौरान आपको सतर्क रहना चाहिए क्योंकि UTF-8 में वर्णों का कुछ संयोजन निषिद्ध है।
विंडोज पर?
विंडोज पर, यह थोड़ा अलग है। Win32 को यूनिकोड के आगमन से पहले, पूरी दुनिया में उत्पादित char
विभिन्न चार्जसेट / कोडपेग के साथ और बहुत से एप्लिकेशन को काम करना पड़ा ।
तो उनका समाधान एक दिलचस्प था: यदि कोई एप्लिकेशन काम करता है char
, तो मशीन पर स्थानीय चारसेट / कोडपेज का उपयोग करके जीयूआई लेबल पर चार तार एन्कोडेड / प्रिंट / दिखाए जाते हैं। उदाहरण के लिए, फ्रांसीसी-स्थानीय विंडोज में "olé" "olé" होगा, लेकिन यदि आप Windows-1251 का उपयोग करते हैं तो एक सिरिलिक-स्थानीयकृत विंडोज ("ol" ) पर कुछ अलग होगा । इस प्रकार, "ऐतिहासिक एप्लिकेशन" आमतौर पर अभी भी उसी पुराने तरीके से काम करेंगे।
यूनिकोड आधारित अनुप्रयोगों के लिए, विंडोज उपयोग करता है wchar_t
, जो 2-बाइट्स चौड़ा है, और UTF-16 में एन्कोडेड है , जो कि यूनिकोड 2-बाइट्स वर्णों पर एन्कोडेड है (या बहुत कम से कम, ज्यादातर संगत यूसीएस -2, जो लगभग है एक ही बात IIRC)।
का उपयोग कर आवेदन char
कहा जाता है "multibyte" (क्योंकि प्रत्येक ग्लिफ़ एक या अधिक से बना है char
, रों) का उपयोग करते समय अनुप्रयोगों wchar_t
कहा जाता है "widechar" (क्योंकि प्रत्येक ग्लिफ़ एक या दो से बना है wchar_t
। देखें MultiByteToWideChar और WideCharToMultiByte अधिक जानकारी के लिए Win32 रूपांतरण एपीआई।
इस प्रकार, यदि आप विंडोज पर काम करते हैं, तो आप बुरी तरह से उपयोग करना चाहते हैं wchar_t
(जब तक कि आप किसी फ्रेमवर्क का उपयोग नहीं करते हैं, जैसे जीटीके + या क्यूटी ...)। तथ्य यह है कि पर्दे के पीछे, विंडोज wchar_t
स्ट्रिंग्स के साथ काम करता है , इसलिए यहां तक कि ऐतिहासिक अनुप्रयोगों char
में wchar_t
एपीआई SetWindowText()
( जैसे Win32 GUI पर लेबल सेट करने के लिए निम्न स्तर एपीआई फ़ंक्शन) का उपयोग करते समय उनके तार परिवर्तित हो जाएंगे ।
मेमोरी के मुद्दे?
UTF-32 प्रति वर्ण 4 बाइट्स है, इसलिए जोड़ने के लिए बहुत कुछ नहीं है, यदि केवल एक UTF-8 पाठ और UTF-16 पाठ हमेशा एक UTF-32 पाठ की तुलना में कम या समान मात्रा का उपयोग करेंगे (और आमतौर पर कम )।
यदि कोई स्मृति समस्या है, तो आपको अधिकांश पश्चिमी भाषाओं की तुलना में जानना चाहिए, UTF-8 पाठ उसी UTF-16 की तुलना में कम मेमोरी का उपयोग करेगा।
फिर भी, अन्य भाषाओं (चीनी, जापानी, आदि) के लिए, उपयोग की जाने वाली मेमोरी या तो यूटीएफ -16 की तुलना में यूटीएफ -8 के लिए या तो समान होगी, या थोड़ी बड़ी होगी।
सभी में, UTF-16 ज्यादातर वर्णों के अनुसार 2 और कभी-कभी 4 बाइट्स का उपयोग करेगा (जब तक कि आप किसी प्रकार की गूढ़ भाषा ग्लिफ़्स (क्लिंगन? एलविश?) के साथ काम नहीं कर रहे हों, जबकि UTF-8 1 से 4 बाइट्स तक खर्च करेगा।
अधिक जानकारी के लिए http://en.wikipedia.org/wiki/UTF-8#Compared_to_UTF-16 देखें ।
निष्कर्ष
जब मुझे std :: wstring over std :: string का उपयोग करना चाहिए?
लिनक्स पर? लगभग नहीं (§)।
विंडोज पर? ज्यादातर हमेशा (§)।
क्रॉस-प्लेटफ़ॉर्म कोड पर? आपके टूलकिट पर निर्भर करता है ...
(Unless): जब तक आप टूलकिट / फ्रेमवर्क का उपयोग नहीं करते हैं अन्यथा नहीं
std::string
विशेष वर्णों सहित सभी ASCII वर्ण सेट कर सकते हैं?
सूचना: A std::string
'बाइनरी' बफर रखने के लिए उपयुक्त है, जहाँ std::wstring
यह नहीं है!
लिनक्स पर? हाँ।
विंडोज पर? Windows उपयोगकर्ता के वर्तमान स्थान के लिए केवल विशेष वर्ण उपलब्ध हैं।
संपादित करें (से एक टिप्पणी के बाद जोहान गेरेल ):
एक std::string
सब संभाल करने के लिए पर्याप्त हो जाएगा char
आधारित तार (प्रत्येक char
0 से 255 के लिए एक नंबर की जा रही है)। परंतु:
- ASCII को 0 से 127 में जाना है। उच्चतर
char
ASCII नहीं हैं।
- एक
char
0 से 127 तक सही ढंग से आयोजित किया जाएगा
- एक
char
128 से 255 अपने एन्कोडिंग (यूनिकोड, गैर यूनिकोड, आदि) के आधार पर एक सार्थकता होगा, लेकिन यह के रूप में वे UTF-8 में इनकोड जब तक सभी यूनिकोड ग्लिफ़ धारण करने के लिए सक्षम हो जाएगा।
है std::wstring
लगभग सभी लोकप्रिय सी ++ compilers द्वारा समर्थित?
ज्यादातर, जीसीसी आधारित संकलक के अपवाद के साथ जो विंडोज पर पोर्ट किए जाते हैं।
यह मेरे g ++ 4.3.2 (लिनक्स के तहत) पर काम करता है, और मैंने विजुअल C ++ 6 के बाद से Win32 पर यूनिकोड एपीआई का उपयोग किया।
वास्तव में एक विस्तृत चरित्र क्या है?
C / C ++ पर, यह एक चरित्र प्रकार लिखा गया है, wchar_t
जो सरल char
चरित्र प्रकार से बड़ा है । इसका उपयोग उन वर्णों के अंदर करने के लिए किया जाता है जिनके सूचकांक (जैसे यूनिकोड ग्लिफ़) 255 (या 127, निर्भर ...) से बड़े होते हैं।