ISO C90 geniş karakter kümeleriyle çalışmak için wchar_t isimli yeni bir veri türü tanımladı. wchar_t dizgelerini doğrudan doğruya çıktılayacak bir olasılıktı eksik olan. Biri onları çok baytlı dizgelere mbstowcs kullanarak çevirdi (hala bir mbsrtowcs yok) ve sonra normal akım işlevlerini kullandı. Bu yapılabilir olurken anlamsız olmayan dönüşümler uyguladığından ve yazılımın karmaşıklığını ve boyutlarını fazlaca arttırdığından çok hantal oldu.
Unix standardı daha erken olarak (XPG4.2'de sanırım) printf ve scanf işlevleri için iki ek biçim belirteci tanımladı. Tek geniş karakterin okunması ve basılması %C belirteci ile geniş karakterli dizgelerinki ise %S belirteci kullanılarak mümkün hale getirildi. Bu belirteçler geniş karakter türü kullanmak dışında tıpkı %c ve %s belirteçleri gibi çalışıyordu. Ancak geniş karakterler ve dizgeler kullanılmadan önce çok baytlı dizgelere ya da tersine çevriliyordu.
Bu bir başlangıçtı ama hala yeterince iyi değildi. printf ve scanf kullanımı hep tercih edilen birşey değildi. Daha küçük ve daha hızlı diğer işlevler geniş karakterlerle çalışamıyordu. İkincisi, printf ve scanf işlevleri için geniş karakterleri oluşturulmasını sağlayacak bir biçim dizgesine sahip değildi. Biçim dizgesi temel olmayan karakterlere sahipse sonuçta biçim dizgesi üretilmiş gibi olurdu.
ISO C 90'ın 1. düzeltmesinde sorunu çözümlemek için yeni bir işlevler kümesi eklendi. Akım işlevlerinin çoğu bir karakter veya dizge yerine bir geniş karakter veya bir geniş karakterli dizge alır hale getirildi. Yeni işlevler aynı akımlar (
stdout gibi) üzerinde işlem yapmaktadır. Bu normal ve geniş karakterler G/Ç işlemleri için ayrı akım işlevleri kullanılan C++ çalışma anı kütüphanesindeki modelden farklıdır.
Aynı akımın hem normal hem de geniş karakterlerle kullanılabilmesi bir sınırlama ile mümkün olur: Bir akım ya normal karakterleri kullanır ya da geniş karakterleri, ikisi birden olmaz. Bir kere karar verildikten sonra dönüşü yoktur. Sadece
freopen ya da
freopen64 işlevleri yönlenimi sıfırlayabilir. Yönlenime üç yolla karar verilebilir:
Normak karakter işlevlerinden biri kullanılmışsa (fread ve fwrite işlevleri dahil) akım "geniş yönlenimli değildir" olarak imlenir.
Geniş karakter işlevlerinden biri kullanılmışsa akım "geniş yönlenimli" olarak imlenir.
Yönlenimi belirlemek için fwide işlevi kullanılır.
Geniş ve geniş olmayan işlemlerin aynı akım üzerinde asla karıştırılmaması gerekliliği önemlidir. Bunun için tasarlanmış bir tanılama yolu yoktur. Uygulama basitçe tuhaflaşır hatta daha basitçe çökebilir. fwide işlevi bundan kaçınmanıza yardımcı olabilir.
int fwide | (FILE *akım,
int kip) |
işlev
fwide işlevi akım yönleniminin belirlenmesinde ve sorgulanmasında kullanılabilir. kip parametresi bir pozitif değer belirtiyorsa akım geniş yönlenimli, negatif bir değer belirtiyorsa dar yönlenimlidir. fwide ile önceki yönlenimi değiştirmek mümkün değildir. akım zaten yönlenimli ise çağrı hiçbir şey yapmaz.
kip sıfırsa, o anki yönlenim durumu sorgulanır ve hiçbir değişiklik yapılmaz.
fwide işlevi yönlenimin durumuna bağlı olarak, dar, hiçbiri veya geniş yönlenimli olmasına göre sırayla bir negatif değer, sıfır veya bir pozitif değerle döner.
Bu işlev ISO C09'ın 1. düzeltmesinde tanımlanmış ve wchar.h başlık dosyasında bildirilmiştir.
Genel olarak bir akımın yönlenimini mümkün olduğu kadar erken belirlemek daha iyidir. Bu özellikle stdin, stdout ve stderr standart akımlarında ortaya çıkacak bazı sürprizlerden sizi koruyabilir. Bu akımlardan birini kullanan bazı kütüphane işlevleri bazı durumlarda akımın yönlenimini uygulamanın kalanında, sonlanma ve hata üretilmesi
dışında farklı bir yolla kullanır. Akımların yönleniminin yanlış kullanımında hata üretilmediğini unutmayın. Bir akımın oluşturulduktan sonra yönlenimsiz bırakılması normalde, sadece akımları farklı bağlamlarda kullanmak üzere oluşturan kütüphane işlevleri için gereklidir.
Akımların kullanıldığı ve bu akımarın farklı bağlamlarda kullanılabildiği bir kodu yazarken bir akımı kullanmadan önce akımın yönlenimini (kütüphane arayüzünün kuralları belli bir yönlenimi talep etmedikçe) sorgulamak önemlidir. Aşağıdaki küçük işlev bunu örneklemektedir:
void
print_f (FILE *fp)
{
if (fwide (fp, 0) > 0)
/* Dönen pozitif değer geniş yönlenimi gösterir. */
fputwc (L'f', fp);
else
fputc ('f', fp);
}
Burada print_f işlevi, akım önceden yönlenimsiz olsa da akımın yönlenimine karar vermektedir (yukarıdaki bilgileri iyi özümlediyseniz olumsuz birşey olmayacağını görürsünüz).
wchar_t değerleri için kullanılan karakter kodlaması belirtilmemiştir ve yazılımcı onun hakkında herhangi bir kabulde bulunmamalıdır. wchar_t değerlerinin G/Ç işlemleri için bunun anlamı, bu değerlerin akıma doğrudan doğruya yazılmasının imkansızlığıdır. Bu ISO C yerel modelinde izlenen yol da değildir. Baytların alttaki ortamdan okunması ve oraya yazılması yerine yapılacak olan önce wchar_t için gerçekleme tarafından seçilen dahili yerele dönüşümdür. Harici karakter kodlaması o anki yerelin LC_CTYPE kategorisi tarafından ya da fopen, fopen64, freopen veya freopen64 işlevlerine verilen kip belirtiminin parçası olan ccs değeri tarafından dönüşümün ne zaman ve nasıl olacağı belirsizdir ve kullanıcıya görünür değildir.
Bir akım yönlenimsiz durumda oluşturulduğunda bu noktada onunla ilişkili bir dönüşüm yapılmaz. Kullanılacak dönüşüm akım yönlenimlendiği sırada LC_CTYPE kategorisi tarafından saptanmış olacaktır. Dikkatli olunmazsa, yerel çalışma anında değiştirilirse sürprizli durumlarla karşılaşabilirsiniz. Bu da, akımın yönleniminin mümkün olduğunca erken belirlenmesinin önemini gösteren iyi bir sebeptir. Şüphesiz bu işlemi bir fwide çağrısı ile yapmalısınız.