Un petit morceau de code me rend fou, mais j’espère que vous pourrez m’empêcher de sauter par la fenêtre. Regardez ici:
#include #include int main() { int8_t i = 65; int8_t j; std::cout << "i = " << i << std::endl; // the 'A' is ok, same as uchar std::cout << "Now type in a value for j (use 65 again): " <> j; std::cout << "j = " << j << std::endl; if (i != j) std::cout << "What is going on here?????" << std::endl; else std::cout << "Everything ok." << std::endl; return 0; }
Si j’utilise int
au lieu de int8_t
tout va bien. J’ai besoin de cela en tant qu’entiers unsigned integers
8 bits, pas plus gros. Et d’ailleurs. avec unsigned char
c’est le même comportement – bien sûr – comme avec int8_t
.
Quelqu’un avec un indice?
int8_t
est un typedef pour un type entier ayant les caractéristiques requirejses: représentation pure en complément à 2, pas de bits de remplissage, taille exacte de 8 bits.
Pour la plupart des compilateurs (peut-être tous), cela signifie qu’il s’agira d’un typedef pour un caractère signed char
(en raison d’un caprice dans la définition du terme type entier signé , il ne peut pas s’agir d’un typedef pour un caractère simple, même si ce caractère est signé).
L’opérateur >>
traite spécialement les types de caractères. La lecture d’un caractère lit un seul caractère saisi, et non une séquence de caractères représentant une valeur entière en décimal. Donc, si le caractère suivant est '0'
, la valeur lue sera la valeur '0'
, probablement 48.
Etant donné qu’une typedef
crée un alias pour un type existant, et non un nouveau type distinct, l’opérateur >>
n’a aucun moyen de savoir que vous souhaitez traiter int8_t
comme un type entier plutôt que comme un type de caractère.
Le problème est que dans la plupart des implémentations, il n’y a pas de type entier 8 bits qui ne soit pas un type de caractère.
La seule solution consiste à lire dans une variable int
puis à convertir en int8_t
(avec des vérifications de plage si vous en avez besoin).
Par ailleurs, int8_t
est un type signé ; le type non signé correspondant est uint8_t
, dans la plage 0..255.
( CHAR_BIT > 8
considération: si CHAR_BIT > 8
, ce qui est autorisé par la norme, alors ni int8_t
ni uint8_t
ne seront définis.)
int8_t
et uint8_t
sont presque certainement des types de caractères ( Int8_t et uint8_t sont-ils destinés à se comporter comme un caractère? ), donc std::cin >> j
lira un seul caractère à partir de stdin et l’interprétera comme un caractère et non comme un nombre.
int8_t
est probablement identique à char
, ce qui signifie que cin >> j
lit simplement un seul caractère ( '6'
) à partir de l’entrée et le stocke dans j
.
int8_t
est défini comme un nom de typedef pour le caractère signed char
. Ainsi, l’ operator >>
utilisé avec un object de type int8_t
se comporte de la même manière qu’il le serait pour un object de type signed char
Les types _t
ne sont pas des types de première classe, mais des alias de type typedef
. int8_t
certaines contraintes. int8_t
exemple, int8_t
est un type pouvant stocker une valeur signée sur 8 bits.
Sur la plupart des systèmes, cela signifie qu’ils sont typedef
et char
. Et comme il s’agit d’un typedef et non d’un type de première classe, vous cin.operator<<(char)
et cin.operator>>(char)
.
Lorsque vous entrez "65", cin.operator>>(char)
consum le '6' et place sa valeur ascii, 54, dans la variable j
.
Pour contourner ce problème, vous devrez utiliser un type différent, la méthode la plus simple étant probablement d’utiliser un type entier plus grand et d’appliquer des contraintes, puis d’abattre:
int8_t fetchInt8(const char* prompt) { int in = 0; for ( ; ; ) { // endless loop. std::cout << prompt << ": "; std::cin >> in; if (in >= std::numeric_limits::min() && in <= std::numeric_limits ::max()) { std::cout << "You entered: " << in << '\n'; // exit the loop break; } std::cerr << "Error: Invalid number for an int8\n"; } return static_cast (in); }
Notez que int8_t est signé, ce qui signifie qu'il stocke -128 à +127. Si vous souhaitez uniquement des valeurs positives, utilisez le type uint8_t.