J'utilise utf8 et dois enregistrer une constante dans un tableau de caractères:
const char s[] = {0xE2,0x82,0xAC, 0}; //the euro sign
Cependant cela me donne une erreur:
test.cpp:15:40: error: narrowing conversion of ‘226’ from ‘int’ to ‘const char’ inside { } [-fpermissive]
Je dois convertir tous les nombres hexadécimaux en caractères, ce qui me semble fastidieux et ne sent pas bon. Y a-t-il une autre manière appropriée de faire cela?
char
peut être signed
ou unsigned
(et la valeur par défaut est spécifique à l'implémentation). Vous voulez probablement
const unsigned char s[] = {0xE2,0x82,0xAC, 0};
ou
const char s[] = "\xe2\x82\xac";
(un string literal est un tableau de char
sauf si vous lui donnez un préfixe)
Voir l'option -funsigned-char (ou -fsigned-char
) de GCC.
Sur certaines implémentations, char
est unsigned
et CHAR_MAX
est 255 (et CHAR_MIN
est 0). Sur les autres char
- s sont signed
donc CHAR_MIN
est -128 et CHAR_MAX
est 127 (et par exemple, les choses sont différentes sous Linux/PowerPC/32 bits et Linux/x86/32 bits). Pour autant que je sache, rien dans la norme n'interdit les caractères signés sur 19 bits.
Bien qu'il puisse être fastidieux de mettre beaucoup de transts dans votre code, cela sent vraiment BON pour moi d'utiliser le plus fort possible de dactylographie.
Comme indiqué ci-dessus, lorsque vous spécifiez le type "char", vous invitez un compilateur à choisir le graveur préféré du compilateur (signé ou non signé). Je ne suis pas un expert en UTF-8, mais il n'y a aucune raison de rendre votre code non portable si vous n'en avez pas besoin.
En ce qui concerne vos constantes, j'ai utilisé des compilateurs qui écrivent les constantes par défaut de cette manière dans les entiers signés, ainsi que des compilateurs qui considèrent le contexte et les interprètent en conséquence. Notez que la conversion entre signé et non signé peut entraîner un débordement excessif. Pour le même nombre de bits, un négatif déborde d'un unsigned (évidemment) et un unsigned avec le bit supérieur défini déborde d'un signé, car le bit supérieur signifie négatif.
Dans ce cas, votre compilateur prend vos constantes comme non signées 8 bits - OU PLUS GRAND - ce qui signifie qu'elles ne tiennent pas comme si elles étaient signées 8 bits. Et nous sommes tous reconnaissants que le compilateur se plaint (du moins je le suis).
Mon point de vue est qu'il n'y a rien de mauvais en ce qui concerne le casting qui montre exactement ce que vous avez l'intention de faire. Et si un compilateur vous permet d’affecter des signatures signées aux des signatures non signées, vous devrez peut-être effectuer le transtypage indépendamment des variables ou des constantes. par exemple
const int8_t a = (int8_t) 0xFF; // sera -1
bien que dans mon exemple, il serait préférable d'attribuer -1. Lorsque vous devez ajouter des conversions supplémentaires, elles ont un sens ou vous devez coder vos constantes afin qu'elles aient du sens pour le type que vous affectez.
La réponse courte à votre question est que vous débordez d'une char
. Une char
a la plage de [-128, 127]. 0xE2 = 226> 127. Ce que vous devez utiliser est un unsigned char
, qui a une plage de [0, 255].
unsigned char s = {0xE2,0x82,0xAC, 0};