SORU
31 Aralık 2008, ÇARŞAMBA


::wstring VS std std::string

std::string std::wstring arasındaki farkları anlamak mümkün değil. wstring Unicode karakterleri gibi geniş karakter destekler biliyorum. Şu sorular var:

  1. std::string std::wstring kullanmalıyım?
  2. std::string tüm ASCII karakter kümesi, özel karakterler de dahil olmak üzere tutabilir?
  3. std::wstring tüm popüler C derleyicileri tarafından desteklenen?
  4. Tam olarak ne olduğunu "geniş bir karakter"?

CEVAP
31 Aralık 2008, ÇARŞAMBA


2**? 3**?

std::string basic_string wchar_t char std::wstring bir şablon oluşturdu.

char vs wchar_t

char 1 baytlık bir karakter bir karakter, genellikle tutmak gerekiyordu. wchar_t geniş bir karakter tutması gereken, ve daha sonra, işler zor olsun: Windows Linux, wchar_t 4-bayt, 2-bytes

ne Unicode o zaman?

Sorun char ne wchar_t ne doğrudan unicode bağlı olmasıdır.

Linux Üzerinde?

Hadi bir Linux OS: Ubuntu sistemim zaten unicode uyumlu. Char bir dize ile çalışmaya başladığımda, doğal olarak UTF-8 kodlanmış (karakter katarı Unicode). Aşağıdaki kodu:

#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(bytes)     :" ;

   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(bytes)    :" ;

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

çıktıları aşağıdaki metin:

sizeof(char)    : 1
text            : olé
sizeof(text)    : 5
strlen(text)    : 4
text(bytes)     : 111 108 195 169

sizeof(wchar_t) : 4
wtext           : UNABLE TO CONVERT NATIVELY.
wtext           : ol�
sizeof(wtext)   : 16
wcslen(wtext)   : 3
wtext(bytes)    : 111 108 233

"Olé" char metin gerçekten dört karakter tarafından inşa edilmiştir: 110, 108, 195 ve (sondaki sıfır saymazsak) 169 göreceksiniz. (Sana bir alıştırma wchar_t kod çalışma) izin veririm

Linux üzerinde bir char ile çalışırken, genellikle bile bilmeden Unicode kullanarak bitirmek gerekir. Ve std::string char ile çalışır, bu yüzden std::string zaten unicode hazır.

Bu not std::string, C string API gibi, "bir dize 4 karakter var, üç değil. olé dikkate alacaktır Karakter bir araya UTF-8'de yasak olduğu için unicode karakter ile oynarken kesiliyor dikkatli olmalı.

Windows?

Windows, bu biraz farklı. Win32 Uygulama çok char çalışma desteği vardı ve tüm dünyadacharsets/codepages farklı üretilen, Unicode gelişiyle önce.

Çözüm ilginç oldu: Eğer bir uygulama GUI etiketleri yerel karakter seti kullanarak gösterilen makinede sayfası/basılı//. kodlanmış char ile çalışır Örneğin, "olé" olur "olé" bir Fransız-yerelleştirilmiş Windows, ama olurdu différent bir Kiril-yerelleştirilmiş Windows ("olй" kullanırsanız Windows-1251). Böylece, "" genellikle hala aynı eski işine yarayacak. tarihi apps

Unicode tabanlı uygulamalar, Windows kullanır wchar_t, 2-bayt geniş ve kodlanmış UTF-16, Unicode kodlanmış 2-bayt karakterler (ya da en azından, çoğunlukla uyumlu USC-2, neredeyse aynı şey IIRC).

Uygulamalar kullanarak char dedi "kısaltması" (çünkü her kabartması oluşan bir veya daha fazla chars), süre uygulamaları kullanarak wchar_t dedi ki, "widechar" (çünkü her kabartması oluşan bir veya iki wchar_t. MultiByteToWideChar WideCharToMultiByte daha fazla bilgi için Win32 API dönüşüm bakın.

Eğer Windows üzerinde çalışıyorsanız böylecefena halde istiyorumwchar_t çerçeve, GTK gibi saklanıyor kullanın veya 45 *...* sürece). Aslında o sahne arkasında, Windows ile çalışır wchar_t dizeleri, hatta tarihsel uygulamaları var onların char dizeleri dönüştürülen wchar_t kullanırken API gibi SetWindowText (düşük seviye API işlevi için ayarlanmış etiketi, win 32 GUI).

Bellek sorunları?

UTF-32 4 bayt başına karakter, yani yok daha ekleyin, eğer sadece bir UTF-8 metin ve UTF-16 metin her zaman daha az veya aynı miktarda bellek daha bir UTF-32 metin (ve genellikle daha az).

Eğer bellek bir sorun varsa, o zaman en Batı dilleri için, UTF-8 metin UTF-16 aynı birden daha az bellek kullanacak daha iyi biliyor olmalısın.

Yine de, diğer diller (Çince, Japonca, vb.), kullanılan bellek ya aynı, ya da UTF-16'dan UTF-8 için büyük olacaktır.

Sonuçta, UTF-16, çoğunlukla karakter başına 2 bayt kullanır ezoterik dil semboller bazı tür ile uğraşıyoruz sürece ((Klingon? Elf?), UTF-8 1 4 bayt harcar.

Daha fazla bilgi için http://en.wikipedia.org/wiki/UTF-8#Compared_to_UTF-16 bkz.

Sonuç

. ben^>1. Std kullanmalıyım zaman::wstring std::string?

Linux Üzerinde? Asla ( § ) neredeyse.
Windows? Her zaman ( § ) neredeyse.
Çapraz plateform kod? Araç bağlıdır...

(§) : bir araç kullandığınız sürece/çerçeve aksini söylüyor

. ben^>2. Std::string özel karakterler de dahil olmak üzere tüm ASCII karakter kümesi tutun?

Dikkat: Bir std::string bir holding için uygundur 'std' tampon,:: wstring değil! ikili

Linux Üzerinde? Evet.
Windows? Sadece özel karakterler Windows kullanıcı mevcut yerel ayarları için kullanılabilir.

Edit (Johann Gerell bir yorum Sonra):bir std::string char göre tüm dizeleri işlemek için yeterli (0 ile 255 arasında bir numara olmak her char) olacaktır. Ama:

  1. ASCII 127 0 olması gerekiyordu. Yüksek ASCII karakter DEĞİL.
  2. 0 127 bir char doğru yapılacak
  3. 255 128 bir char bir anlamlandırma senin kodlama (unicode, unicode, vb.) bağlı olarak, olacak ama tüm Unicode semboller UTF-8 kodlanmış olarak tutmak mümkün olacak.

. ben^>3. Std::wstring neredeyse tüm popüler C derleyicileri tarafından desteklenen?

Çoğunlukla, Windows için bağlantı noktası kurulmuş bir GCC tabanlı uygulamaları hariç
Benim g 4.3.2 üzerinde çalışır (Linux altında), ve Görsel beri Win32 API Unicode C 6 kullandım.

. ben^>4. Tam olarak geniş bir karakter nedir?

C/C üzerinde, char basit karakter türü daha büyük olan bir karakter tipi wchar_t yazıyor. 255'ten daha büyük olan içindeki karakterler (veya 127, göre...) koymak için kullanılan gerekiyordu

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • André Frizzo

    André Frizz

    16 Aralık 2006
  • Jonathan Morrison

    Jonathan Mor

    24 Mart 2010
  • njhaley

    njhaley

    24 NİSAN 2006