Wchar_t nedir?
wchar_t, herhangi bir yerelin karakter kodlamasının, her wchar_t'nin tam olarak bir kod noktasını temsil ettiği bir wchar_t gösterimine dönüştürülebileceği şekilde tanımlanır:
Tür wchar_t, değerleri desteklenen yerel ayarlar (22.3.1) arasında belirtilen en büyük genişletilmiş karakter kümesinin tüm üyeleri için farklı kodları temsil edebilen farklı bir türdür.
- C ++ [temel. Temel] 3.9.1 / 5
Bu , wchar_t'nin tüm yerel ayarlardan aynı anda herhangi bir karakteri temsil edecek kadar büyük olmasını gerektirmez. Yani, wchar_t için kullanılan kodlama yerel ayarlar arasında farklılık gösterebilir. Bu, bir dizgeyi bir yerel ayar kullanarak wchar_t'ye dönüştüremeyeceğiniz ve ardından başka bir yerel ayar kullanarak char'a geri dönüştüremeyeceğiniz anlamına gelir. 1
Wchar_t'yi tüm yerel ayarlar arasında ortak bir temsil olarak kullanmak, pratikte wchar_t için birincil kullanım gibi göründüğünden, o değilse ne için iyi olduğunu merak edebilirsiniz.
Wchar_t'nin asıl amacı ve amacı, bir dizenin kod birimlerinden metnin karakterlerine bire bir eşleştirme gerektirecek şekilde tanımlayarak metin işlemeyi basitleştirmektir, böylece kullanılanlarla aynı basit algoritmaların kullanımına izin verir. diğer dillerle çalışmak için ascii dizeleri ile.
Maalesef wchar_t'nin belirtimindeki ifade, bunu başarmak için karakterler ve kod noktaları arasında bire bir eşleştirme olduğunu varsayar. Unicode bu 2 varsayımını bozduğundan, wchar_t'yi basit metin algoritmaları için de güvenle kullanamazsınız.
Bu, taşınabilir yazılımın wchar_t'yi yerel ayarlar arasındaki metnin ortak bir temsili olarak veya basit metin algoritmalarının kullanımını etkinleştirmek için kullanamayacağı anlamına gelir.
Wchar_t bugün ne işe yarar?
Zaten taşınabilir kod için fazla değil. Eğer __STDC_ISO_10646__
tanımlanmışsa, wchar_t değerleri doğrudan tüm yerel ayarlarda aynı değerlere sahip Unicode kod noktalarını temsil eder. Bu, daha önce bahsedilen yerel ayarlar arası dönüşümleri yapmayı güvenli hale getirir. Bununla birlikte, yalnızca wchar_t'yi bu şekilde kullanabileceğinize karar vermek için ona güvenemezsiniz çünkü çoğu unix platformu onu tanımlarken, Windows tüm yerel ayarlarda aynı wchar_t yerel ayarını kullansa bile Windows bunu yapmaz.
Windows'un tanımlamamasının __STDC_ISO_10646__
nedeni, Windows'un wchar_t kodlaması olarak UTF-16 kullanması ve UTF-16'nın U + FFFF'den daha büyük kod noktalarını temsil etmek için yedek çiftler kullanmasıdır, bu da UTF-16'nın gereksinimlerini karşılamadığı anlamına gelir __STDC_ISO_10646__
.
Platforma özel kod için wchar_t daha kullanışlı olabilir. Esasen Windows'ta gereklidir (örneğin, bazı dosyalar wchar_t dosya adları kullanılmadan açılamaz), ancak Windows bildiğim kadarıyla bunun doğru olduğu tek platformdur (bu nedenle wchar_t'yi 'Windows_char_t' olarak düşünebiliriz).
Geriye dönüp bakıldığında wchar_t, metin işlemeyi basitleştirmek için veya yerel ayardan bağımsız metin için depolama olarak açıkça kullanışlı değildir. Taşınabilir kod, onu bu amaçlar için kullanmaya çalışmamalıdır. Taşınabilir olmayan kod, yalnızca bazı API gerektirdiği için yararlı bulabilir.
Alternatifler
Sevdiğim alternatif, UTF-8'e özellikle uygun olmayan platformlarda bile UTF-8 kodlu C dizgilerini kullanmaktır.
Bu şekilde, platformlar arasında ortak bir metin temsili kullanarak taşınabilir kod yazabilir, amaçlanan amaçları için standart veri türlerini kullanabilir, bu türler için dilin desteğini alabilir (örneğin, bazı derleyiciler için çalışmasını sağlamak için bazı hileler gerekli olsa da, dize değişmezleri), bazıları standart kütüphane desteği, hata ayıklayıcı desteği (daha fazla numara gerekli olabilir), vb. Geniş karakterlerle tüm bunları elde etmek genellikle daha zordur veya imkansızdır ve farklı platformlarda farklı parçalar elde edebilirsiniz.
UTF-8'in sağlamadığı bir şey, ASCII ile mümkün olanlar gibi basit metin algoritmalarını kullanma yeteneğidir. Bu UTF-8'de diğer Unicode kodlamalardan daha kötü değildir. Aslında, UTF-8'deki çoklu kodlu birim gösterimleri daha yaygın olduğu için daha iyi olduğu düşünülebilir ve bu nedenle, karakterlerin bu tür değişken genişlikli temsillerini işlemede kodun işlenmesindeki hataların, UTF'ye bağlı kalmaya çalışmanıza göre fark edilmesi ve düzeltilmesi daha olasıdır. NFC veya NFKC ile -32.
Pek çok platform UTF-8'i yerel karakter kodlaması olarak kullanır ve birçok program önemli bir metin işleme gerektirmez ve bu nedenle bu platformlarda uluslararasılaştırılmış bir program yazmak, uluslararasılaştırmayı dikkate almadan kod yazmaktan biraz farklıdır. Daha geniş çapta taşınabilir kod yazmak veya diğer platformlarda yazmak, diğer kodlamaları kullanan API'lerin sınırlarına dönüştürmeler eklemeyi gerektirir.
Bazı yazılımlar tarafından kullanılan başka bir alternatif, UTF-16 verilerini tutan işaretsiz kısa diziler gibi çapraz platform temsilini seçmek ve ardından tüm kitaplık desteğini sağlamak ve dil desteğindeki maliyetlerle yaşamaktır.
C ++ 11, görevli dil / kitaplık özellikleriyle wchar_t, char16_t ve char32_t seçeneklerine alternatif olarak yeni tür geniş karakterler ekler. Bunların UTF-16 ve UTF-32 olması garanti edilmiyor, ancak herhangi bir büyük uygulamanın başka bir şey kullanacağını düşünmüyorum. C ++ 11 ayrıca UTF-8 desteğini de geliştirir, örneğin UTF-8 dize değişmezleri ile VC ++ 'yı UTF-8 kodlu dizeler üretmek için kandırmaya gerek kalmaz (ancak u8
öneki kullanmak yerine bunu yapmaya devam edebilirim ) .
Kaçınılması gereken alternatifler
TCHAR: TCHAR, eski kodlamaları char'dan wchar_t'ye taşıyan eski Windows programlarını taşımak içindir ve programınız daha önceki bin yılda yazılmadıysa en iyisi unutulur. Taşınabilir değildir ve kodlaması ve hatta veri türü konusunda doğası gereği belirsizdir, bu da onu TCHAR tabanlı olmayan herhangi bir API ile kullanılamaz hale getirir. Amacı yukarıda gördüğümüz wchar_t'ye geçiş olduğu için iyi bir fikir olmadığından, TCHAR kullanmanın hiçbir değeri yoktur.
1. wchar_t dizelerinde gösterilebilen ancak herhangi bir yerel ayarda desteklenmeyen karakterlerin tek bir wchar_t değeriyle temsil edilmesi gerekmez. Bu, wchar_t'nin belirli karakterler için değişken genişlik kodlaması kullanabileceği anlamına gelir, bu da wchar_t'nin amacının bir başka açık ihlali. Wchar_t ile temsil edilebilen bir karakterin, yerel ayarın bu karakteri 'desteklediğini' söylemek için yeterli olduğu tartışılabilir olsa da, bu durumda değişken genişlikli kodlamalar yasal değildir ve Window'un UTF-16 kullanımı uyumlu değildir.
2. Unicode, birçok karakterin birden çok kod noktasıyla temsil edilmesine izin verir, bu da basit metin algoritmaları için değişken genişlik kodlamalarıyla aynı sorunları yaratır. Bir kişi birleşik bir normalleştirmeyi kesinlikle sürdürse bile, bazı karakterler yine de birden çok kod noktası gerektirir. Bakınız: http://www.unicode.org/standard/where/