web-dev-qa-db-fra.com

Utilisation d'Unicode dans le code source C ++

Quel est l'encodage standard du code source C++? Le standard C++ en dit-il même quelque chose? Puis-je écrire une source C++ en Unicode?

Par exemple, puis-je utiliser des caractères non ASCII tels que des caractères chinois dans les commentaires? Si tel est le cas, Unicode complet est-il autorisé ou seulement un sous-ensemble d'Unicode? (par exemple, cette première page 16 bits ou son nom.)

De plus, puis-je utiliser Unicode pour les chaînes? Par exemple:

Wstring str=L"Strange chars: â Țđ ě €€";
53
Kresimir Cosic

L'encodage en C++ est assez compliqué. Voici ma compréhension de cela.

Chaque implémentation doit prendre en charge les caractères du jeu de caractères source de base. Il s'agit notamment des caractères communs répertoriés au §2.2/1 (§2.3/1 en C++ 11). Ces caractères doivent tous tenir dans un char. De plus, les implémentations doivent prendre en charge un moyen de nommer d'autres caractères en utilisant un moyen appelé universal-character-names et ressemble à \uffff ou \Uffffffff et peut être utilisé pour faire référence aux caractères Unicode. Un sous-ensemble d'entre eux sont utilisables dans les identifiants (énumérés à l'annexe E).

Tout cela est bien, mais le mappage des caractères du fichier aux caractères source (utilisés au moment de la compilation) est défini par l'implémentation. Ceci constitue l'encodage utilisé. Voici ce qu'il dit littéralement (version C++ 98):

Les caractères du fichier source physique sont mappés, d'une manière définie par l'implémentation, au jeu de caractères source de base (en introduisant des caractères de nouvelle ligne pour les indicateurs de fin de ligne) si nécessaire. Les séquences de trigraph (2.3) sont remplacées par des représentations internes à caractère unique correspondantes. Tout caractère de fichier source qui ne fait pas partie du jeu de caractères source de base (2.2) est remplacé par le nom de caractère universel qui désigne ce caractère. (Une implémentation peut utiliser n'importe quel encodage interne, tant qu'un caractère étendu réel rencontré dans le fichier source, et le même caractère étendu exprimé dans le fichier source comme un nom de caractère universel (c'est-à-dire en utilisant la notation\uXXXX), sont gérés de manière équivalente.)

Pour gcc, vous pouvez le changer en utilisant l'option -finput-charset=charset. En outre, vous pouvez modifier le caractère d'exécution utilisé pour réinitialiser les valeurs lors de l'exécution. L'option appropriée pour cela est -fexec-charset=charset pour char (il s'agit par défaut de utf-8) et -fwide-exec-charset=charset (par défaut, soit utf-16 ou utf-32 selon la taille de wchar_t).

34

Le standard C++ ne dit rien sur l'encodage des fichiers de code source, pour autant que je sache.

Le codage habituel est (ou était) 7 bits ASCII - certains compilateurs (Borland, par exemple) rechignaient à ASCII caractères qui utilisaient le Il n'y a aucune raison technique pour laquelle les caractères Unicode ne peuvent pas être utilisés, si votre compilateur et votre éditeur les acceptent - les outils les plus modernes basés sur Linux et bon nombre des meilleurs éditeurs basés sur Windows, gèrent l'encodage UTF-8 sans problème, même si je ne suis pas sûr que le compilateur de Microsoft le fera.

EDIT: Il semble que les compilateurs de Microsoft acceptent les fichiers codés Unicode, mais génèrent parfois des erreurs sur 8 bits ASCII aussi:

warning C4819: The file contains a character that cannot be represented
in the current code page (932). Save the file in Unicode format to prevent
data loss.
10
Head Geek

En plus de l'article de litb, MSVC++ prend également en charge Unicode. Je comprends qu'il obtient l'encodage Unicode de la nomenclature. Il prend certainement en charge du code comme int (*♫)(); ou const std::set<int> ∅; Si vous aimez vraiment le brouillage du code:

typedef void ‼; // Also known as \u203C
class ooɟ {
    operator ‼() {}
};
9
MSalters

Il y a deux problèmes en jeu ici. Le premier est quels caractères sont autorisés dans le code C++ (et les commentaires), tels que les noms de variables. La seconde est quels caractères sont autorisés dans les chaînes et les littéraux de chaîne.

Comme indiqué, les compilateurs C++ must prennent en charge un jeu de caractères ASCII très restreint pour les caractères autorisés dans le code et les commentaires. Dans la pratique, ce jeu de caractères ne fonctionnait pas très bien avec certains jeux de caractères européens (et surtout avec certains claviers européens qui n'avaient pas quelques caractères - comme des crochets - disponibles), donc le concept de digraphes et trigraphes était introduit. De nombreux compilateurs acceptent plus que ce jeu de caractères pour le moment, mais il n'y a aucune garantie.

En ce qui concerne les chaînes et les littéraux de chaîne, C++ a le concept d'un caractère large et d'une chaîne de caractères large. Cependant, l'encodage pour ce jeu de caractères n'est pas défini. En pratique, c'est presque toujours Unicode, mais je ne pense pas qu'il y ait de garantie ici. Les littéraux de chaîne de caractères larges ressemblent à L "littéral de chaîne", et ceux-ci peuvent être attribués à std :: wstring.


C++ 11 a ajouté la prise en charge explicite des chaînes et des littéraux de chaîne Unicode, encodés en UTF-8, UTF-16 big endian, UTF-16 little endian, UTF-32 big endian et UTF-32 little endian.

6
Max Lybbert

Pour l'encodage en chaînes, je pense que vous êtes censé utiliser la notation \, par exemple:

std::wstring str = L"\u20AC"; // Euro character
3
Rob

Dans ce contexte, si vous recevez l'avertissement MSVC++ C4819, remplacez simplement le codage du fichier source par "UTF-8 with Bom".

GCC 4.1 ne le prend pas en charge, mais GCC 4.4 le fait, et la dernière version de Qt utilise GCC 4.4, donc utilisez "UTF-8 avec Bom" comme codage du fichier source.

2
raidsan

Il convient également de noter que les caractères larges en C++ ne sont pas vraiment des chaînes Unicode en tant que tels. Ce ne sont que des chaînes de caractères plus gros, généralement 16, mais parfois 32 bits. Ceci est défini par l'implémentation, cependant, IIRC vous pouvez avoir un _ 8 bits wchar_t Vous n'avez aucune garantie réelle quant à leur encodage, donc si vous essayez de faire quelque chose comme le traitement de texte, vous voudrez probablement un typedef du type entier le plus approprié pour votre entité Unicode.

C++ 1x prend en charge unicode supplémentaire sous la forme de littéraux de chaîne de codage UTF-8 (u8"text") et les types de données UTF-16 et UTF-32 (char16_t et char32_t IIRC) ainsi que les constantes de chaîne correspondantes (u"text" et U"text"). L'encodage sur les caractères spécifiés sans \uxxxx ou \Uxxxxxxxx les constantes sont toujours définies par l'implémentation (et il n'y a pas de support d'encodage pour les types de chaînes complexes en dehors des littéraux)

2
coppro

AFAIK Ce n'est pas standardisé car vous pouvez mettre n'importe quel type de caractères en chaînes larges. Il vous suffit de vérifier que votre compilateur est défini sur le code source Unicode pour le faire fonctionner correctement.

0
Klaim