web-dev-qa-db-fra.com

Comment initialiser un tableau de caractères en utilisant des nombres hexadécimaux?

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?

9
texasbruce

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.

17

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.

0
Mike Layton

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};
0
Zac Howland