::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:
std::string
std::wstring
kullanmalıyım?std::string
tüm ASCII karakter kümesi, özel karakterler de dahil olmak üzere tutabilir?std::wstring
tüm popüler C derleyicileri tarafından desteklenen?- Tam olarak ne olduğunu "geniş bir karakter"?
CEVAP
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 char
s), 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:
- ASCII 127 0 olması gerekiyordu. Yüksek ASCII karakter DEĞİL.
- 0 127 bir char doğru yapılacak
- 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
CString dönüştürmek için nasıl ::std::...
JavaScript, basit bir beşgen kullanmak...
JavaScript string Trim?...
Python katılın, neden dize.liste yerin...
JavaScript string özellik değeri nesne...