C++ caractères unicode impression
J'ai besoin d'imprimer des caractères unicode sur le terminal Linux à l'aide de iostream
. Des choses étranges se passent bien. Quand j'écris:
cout << "\u2780";
J'obtiens: ➀
, qui est presque exactement ce que je veux. Cependant, si j'écris:
cout << '\u2780';
J'obtiens: 14851712
.
Le problème est, je ne sais pas exactement quel caractère pour être imprimé au moment de la compilation. C'est pourquoi j'aimerais faire quelque chose comme:
int x;
//some calculations...
cout << (char)('\u2780' + x);
Qui imprime: �
. À l'aide de wcout
ou wchar_t
au lieu de cela ne fonctionne pas non plus. Comment puis-je obtenir une impression correcte?
De ce que j'ai trouvé sur l'Internet, il semble important que j'utilise g++ 4.7.2 compilateur directement à partir de Debian Wheezy référentiel.
L
? poste ton code complet si possible ou une [sscce.org](SSCCE)Si vous ne voulez pas salir avec les codages Unicode, vous pouvez utiliser une table pour les chaînes de valeurs possibles de
x
plutôt que de l'ajouter.Double Possible de Comment faire pour imprimer des caractères Unicode en C++?
OriginalL'auteur Sventimir | 2013-06-05
Vous devez vous connecter pour publier un commentaire.
Le caractère Unicode
\u2780
est en dehors de la plage de lachar
type de données. Vous devriez avoir reçu ce message d'avertissement du compilateur de vous en parler: (au moins de mon g++ 4.7.3 lui donne)Si vous souhaitez travailler avec des personnages comme U+2780 comme les unités simples que vous aurez à utiliser la widechar type de données
wchar_t
, ou si vous êtes assez chanceux pour être en mesure de travailler avec C++11,char32_t
ouchar16_t
. Notez que l'une des 16 bits de l'unité n'est pas suffisant pour représenter la gamme complète de caractères Unicode.Si cela ne fonctionne pas pour vous, c'est probablement parce que la valeur par défaut "C" locale n'est pas prise en charge pour les non-ASCII sortie. Pour résoudre ce problème, vous pouvez appeler
setlocale
dans le début du programme; de cette façon, vous pouvez afficher la gamme complète de caractères pris en charge par la locale de l'utilisateur: (qui peut ou peut ne pas avoir un soutien pour tous les caractères que vous utilisez)sizeof(wchar_t) < 4
. Je vous suggère de l'aidechar16_t
ouchar32_t
btw.en outre, le codage préfixe
L
, il y au8
pourUTF8
encodage,u
pourchar16_t
, etU
pourchar32_t
.setlocale
lors du passage d'un""
pour le nom de la langue jeux préférés de l'utilisateur paramètres régionaux, qui n'est pas nécessairement une Unicode locale.Merci @DyP, j'ai ajouté la note sur le nouveau personnage types de données.
IIRC elles, support de l'Unicode pour les flux de données en C++11; il n'y a pas de support pour
wcout <<
avec unchar16_t
etchar32_t
. Vous devrez soit faire une coutume de conversion de celles attendues d'encodage dewchar_t
ou de l'utilisation non formaté de sortie.OriginalL'auteur Joni
Lorsque vous écrivez
Le compilateur convertit \u2780 dans le codage approprié de ce caractère dans l'exécution de jeu de caractères. C'est probablement l'UTF-8, et la chaîne finit par avoir quatre octets (trois pour le personnage, l'un pour le terminateur null).
Si vous souhaitez générer le personnage au moment de l'exécution, alors vous devez trouver un moyen de le faire au moment de l'exécution de la même conversion en UTF-8, que le compilateur est en train de faire au moment de la compilation.
C++11, une pratique
wstring_convert
modèle et codecvt facettes qui peut faire cela, cependant libstdc++, de la bibliothèque standard de mise en œuvre qui vient avec gcc, n'a pas encore eu l'occasion de les mettre en œuvre (comme gcc 4.8). Ce qui suit montre comment utiliser ces fonctionnalités, mais vous aurez besoin d'utiliser un autre standard de mise en œuvre de bibliothèque ou d'attendre libstdc++ pour les mettre en œuvre.Vous pouvez également utiliser toute autre méthode de production d'UTF-8, vous avez à disposition. Par exemple, iconv, soins intensifs, et le manuel d'utilisation de pré-C++11 codecvt_byname facettes seraient tous travaux. (Je n'ai pas de montrer des exemples de celles-ci, parce que le code serait plus que de la simple code permise par la
wstring_convert
.)Une alternative qui permettrait de travail pour un petit nombre de personnages, il faudrait créer un tableau de chaînes de caractères à l'aide de littéraux.
OriginalL'auteur bames53
Le programme imprime un entier en raison de C++11 §2.14.3/1:
L'exécution jeu de caractères est ce que
char
peut représenter, c'est à dire ASCII.Ce que vous avez obtenu est 14851712, ou en hexadécimal e29e80, qui est l'UTF-8 est une représentation de U+2780. Mettre UTF-8, un encodage multi-octets, dans un
int
est fou et stupide, mais c'est ce que vous obtenez à partir d'un "conditionnellement pris en charge, la mise en œuvre définies".Pour obtenir un UTF-32 valeur, utilisez
U'\u2780'
. La premièreU
spécifie lechar32_t
type et UTF-32 encodage (c'est à dire jusqu'à 31 bits, mais pas de paires de substitution). La deuxième\u
spécifie universel de caractères contenant le nom de code de point. Pour obtenir une valeur soi-disant compatible avecwcout
, utilisezL'\u2780'
, mais cela ne veut pas nécessairement utiliser une Unicode valeur d'exécution, ni vous obtenez plus de deux octets de stockage.Comme fiable de la manipulation et de l'impression de l'Unicode codepoint, comme d'autres réponses l'ont noté, la norme C++ n'a pas vraiment eu là encore. Joni réponse est la meilleure façon, mais encore, il suppose que le compilateur et l'environnement de l'utilisateur utilisez les mêmes paramètres régionaux, qui, souvent, n'est pas vrai.
Vous pouvez également spécifier des chaînes UTF-8 dans la source à l'aide de
u8"\u2780"
force et de l'environnement d'exécution de l'UTF-8 en utilisant quelque chose commestd::locale::global( std::locale( "en_US.UTF-8" ) );
. Mais qui a encore des bords rugueux. Joni suggère l'utilisation de l'interface Cstd::setlocale
de<clocale>
au lieu de l'interface C++std::locale::global
de<locale>
, qui est une solution de contournement à l'interface C++ être cassé dans GCC sur OS X et peut-être d'autres plates-formes. Les questions sont d'une plate-forme assez sensibles que votre distribution Linux, pourrait bien avoir mis un patch dans leur propre pack GCC.Apparemment, il n'est pas pris en charge dans GCC 4.7.2, mais ça fait partie du C++11. Juste aller avec
L'xxx'
; sous Linux il doit faire essentiellement la même chose.L'ajout de C++11 avec
gcc --std=c++11
appel ne fonctionne pas non plus. Il regroupe, mais les tirages valeur décimale du char (10112), pas le char lui-même.OriginalL'auteur Potatoswatter
Dans Linux, j'ai réussi l'impression d'unicode directement dans LA plus naïve façon:
OriginalL'auteur quanta