2010-02-03 5 views
3

wcstombs documentation dit, il "convertit la séquence de codes de caractères larges en chaîne multi-octets". Mais il ne dit jamais ce qu'est un "caractère large".wcstombs: encodage de caractères?

Est-il implicite, comme dire qu'il convertit utf-16 en utf-8 ou la conversion est définie par une variable d'environnement?

De même, quel est le cas d'utilisation typique de wcstombs?

+0

Un "caractère large" est un 'wchar_t'. – kennytm

Répondre

4

Vous utilisez la fonction standard setlocale() avec la catégorie LC_CTYPE (ou LC_ALL) pour définir la correspondance entre la bibliothèque utilise wchar_t caractères et les caractères multi-octets. Le nom de locale proprement dit transmis à setlocale() est défini par l'implémentation, vous devrez donc le rechercher dans les documents de votre compilateur.

Par exemple, vous pouvez utiliser MSVC

setlocale(LC_ALL, ".1252"); 

pour définir le runtime C à utiliser comme codepage 1252 le jeu de caractères multi-octets. Notez que MSVC docs indique explicitement que les paramètres régionaux ne peut pas être réglé sur UTF-7 ou UTF8 pour les jeux de caractères multi-octets:

L'ensemble des langues disponibles, codes pays/région, et les pages de code comprend tous ceux pris en charge par le API Win32 NLS sauf les pages de code qui nécessitent plus de deux octets par caractère, telles que UTF-7 et UTF-8. Si vous fournissez une page de code comme UTF-7 ou UTF-8, setlocale échouera, retournant NULL.

Le « grand caractère » type wchar_t est destiné à être en mesure de soutenir un caractère défini le système prend en charge - la norme ne définit pas la taille d'un type wchar_t (il pourrait être aussi petit qu'un char ou l'un des types entiers plus grands). Sous Windows, il s'agit du codage Unicode «interne» du système, qui est UTF-16 (UCS-2 avant WinXP). Honnêtement, je ne trouve pas de citation directe dans les documents du MSVC. Strictement parlant, la mise en œuvre devrait appeler cela, mais je ne peux pas le trouver.

+2

Attention: il n'y a pas de standard pour la chaîne locale dans setlocale, il n'est donc pas facile de faire quoi que ce soit sur plusieurs plateformes. Par exemple, .1252 est valide sur Windows, mais pas sur UNIX/Linux (vous y verrez des choses comme en_US.UTF-8 ou en_US.iso889-1) –

1

Les chaînes de caractères larges sont composées de caractères multi-octets, alors que la chaîne C normale est une char * - une séquence de caractères au format octet. Whars ne sont pas la même chose qu'unicode sur toutes les plateformes, bien que les représentations unicode sont généralement basées sur wchar_t

J'ai vu wchars utilisés dans les systèmes embarqués comme les téléphones, où vous voulez des noms de fichiers avec des caractères spéciaux, mais ne veulent pas nécessairement soutenir toute la gloire et la complexité de l'Unicode.

utilisation typique serait de convertir une chaîne de caractères sur la base de 2 octets en une chaîne régulière de C, et Vica versa

+0

Ceci est peut-être un peu déroutant - dans ce cas et des usages similaires, une "chaîne multi-octets" est une chaîne faite de caractères - un "standard ansi c-string", mais où il peut y avoir plus d'un caractère (byte) caractère logique, alors qu'une chaîne large alloue généralement plus de 1 octet par élément (sizeof (wchar_t) == 2 est commun), souvent initialement dans la croyance erronée que cela permettrait au nombre de caractères logiques dans une chaîne d'égaler le nombre d'éléments. –

1

Selon le standard C, du type wchar_t est « capable de représenter tous les caractères de la localisation en cours ». La norme ne dit pas quel est le codage pour wchar_t. En fait, les limites sur WCHAR_MIN et WCHAR_MAX sont [0, 255] ou [-127, 127], selon que wchar_t est non signé ou signé.

Un caractère multi-octets peut utiliser plusieurs octets. Une chaîne multi-octets est composée d'un ou de plusieurs caractères multi-octets. Dans une chaîne multi-octets, chaque caractère n'a pas nécessairement le même nombre d'octets (UTF-8 est un exemple). Considérant que, un objet de type wchar_t a une taille fixe (dans une implémentation donnée, bien sûr).

En aparté, je peux aussi trouver ce qui suit dans ma copie du projet C99:

__STDC_ISO_10646__ Une constante entière de la forme yyyymmL (par exemple, 199712L). Si ce symbole est défini, chaque caractère de l'ensemble Unicode requis, lorsqu'il est stocké dans un objet de type wchar_t, a la même valeur que l'identificateur court de ce caractère. L'ensemble Unicode requis comprend tous les caractères définis par l'ISO/CEI 10646, ainsi que tous les amendements et corrigenda techniques, pour l'année et le mois spécifiés.

Donc, si je comprends bien, si __STDC_ISO_10646__ est définie, wchar_t peut stocker des caractères Unicode.

+0

La limite réelle sur 'WCHAR_MAX' n'est pas' 255' (Vous confondez probablement avec le type 'char'). Selon 'c11' (' c99' ont aussi la même description): 'la valeur de ** WCHAR_MAX ** ne doit pas être inférieure à 255.'. La valeur réelle peut être '2147483647'. Exemple en direct [ici] (http://melpon.org/wandbox/permlink/zQmKmfSJET4nHkcY). Je n'ai jamais vu si c'était '255'. – alexolut

3

Il convertit tout ce que votre plate-forme utilise pour un "char" large (que je crois être en fait UCS2 sous Windows, mais est généralement UCS4 sous UNIX) en encodage de caractères multi-octets par défaut. Si votre locale est un UTF-8, alors c'est le codage multi-octets qui sera utilisé - mais notez qu'il existe d'autres possibilités, comme JIS.

+2

Sur Windows qui est UTF-16, pas UCS2. –

+0

Assez juste. (Cela semble quelque peu brisé - le point entier de widechars était censé être qu'un widechar est toujours exactement un caractère). – caf

+0

Ce n'est jamais vrai. Même un widechar 32 bits sous Linux peut représenter un élément non imprimable comme une partie d'un caractère accentué décomposé, ou une directive d'ordre RTL, ou toutes sortes d'autres choses. Il n'est donc jamais prudent de supposer qu'un point de code est un caractère, quel que soit le codage. – Miral