543 votes

Convertir char en int en C et C++

Comment convertir un char à un int en C et C++ ?

3 votes

@Matt : ce serait une bonne idée d'être plus concret. demander une généralisation ne fait qu'inviter des réponses généralisées qui sont sans objet ou même correct pour votre tâche. gardez à l'esprit que lorsque vous devez demander, vous n'en savez probablement pas assez pour généraliser correctement.

1 votes

@Alf P. Steinbach : La question initiale était vague concernant la langue. Avec des mots-clés c y c++ je pense que les réponses confrontant les deux langues sont raisonnables.

11 votes

D'après ma vaste expérience sur d'autres forums techniques, mon intuition est que le PO vraiment signifie "comment puis-je prendre la représentation textuelle d'un nombre (en base 10) et la convertir en nombre correspondant ?". D'une manière générale, les néophytes du C et du C++ ont généralement incroyablement des idées floues sur la façon dont le texte fonctionne dans ces langues et sur ce qu'il faut faire. char signifie vraiment.

729voto

Foo Bah Points 11566

Cela dépend de ce que vous voulez faire :

pour lire la valeur comme un code ascii, vous pouvez écrire

char a = 'a';
int ia = (int)a; 
/* note that the int cast is not necessary -- int ia = a would suffice */

pour convertir le caractère '0' -> 0 , '1' -> 1 etc, vous pouvez écrire

char a = '4';
int ia = a - '0';
/* check here if ia is bounded by 0 and 9 */

Explication :
a - '0' est équivalent à ((int)a) - ((int)'0') ce qui signifie que les valeurs ascii des caractères sont soustraites les unes des autres. Puisque 0 vient directement avant 1 dans la table ascii (et ainsi de suite jusqu'à ce que 9 ), la différence entre les deux donne le nombre que le caractère a représente.

2 votes

@KshitijBanerjee Ce n'est pas une bonne idée pour deux raisons : cela vous donne un nombre négatif pour les caractères ascii avant '0' (comme & -> -10), et il vous donne des nombres supérieurs à 10 (comme x -> 26)

2 votes

Int ia = a - '0' - c'est ce dont vous avez besoin

5 votes

@kevin001 Si vous voulez convertir le char en int et un caractère '1' fournit un nombre ascii qui n'est pas 1 vous devez enlever le décalage '0' pour le réaligner afin de compter de 0 à 9. Les chiffres consécutifs 1-9 sont adjacents dans le nombre entier ascii.

65voto

Matt Joiner Points 29194

C et C++ promeuvent toujours les types à au moins int . De plus, les littéraux de caractères sont de type int en C et char en C++.

Vous pouvez convertir un char simplement en l'assignant à un int .

char c = 'a'; // narrowing on C
int a = c;

3 votes

Vous pouvez également utiliser le très peu apprécié unaire operator+() à cette fin.

25 votes

-1 La réponse est incorrecte pour la seule interprétation significative de la question. Ceci (code int a = c; ) conservera toute valeur négative, ce que les fonctions de la bibliothèque standard du C ne peuvent pas gérer. Les fonctions de la bibliothèque standard du C définissent la norme pour ce qui est de la manipulation de char comme int .

0 votes

@Nawaz - ...en supposant qu'il veut un simple tuyau de type plutôt qu'une véritable conversion.

40voto

Lundin Points 21616

Char est juste un entier de 1 octet. Il n'y a rien de magique avec le type char ! Tout comme vous pouvez affecter un short à un int, ou un int à un long, vous pouvez affecter un char à un int.

Oui, le nom du type de données primitif est "char", ce qui laisse entendre qu'il ne doit contenir que des caractères. Mais en réalité, "char" n'est qu'un mauvais choix de nom pour embrouiller tous ceux qui essaient d'apprendre le langage. Un meilleur nom pour ce type de données est int8_t, et vous pouvez utiliser ce nom à la place, si votre compilateur suit la dernière norme C.

Bien que, bien sûr, vous devrait Utilisez le type char lorsque vous manipulez des chaînes de caractères, car l'index de la table ASCII classique tient dans un octet. Vous pouvez consulter le site pourrait Cependant, il est également possible de manipuler des chaînes de caractères avec des ints ordinaires, bien qu'il n'y ait aucune raison pratique dans le monde réel de vouloir le faire. Par exemple, le code suivant fonctionnera parfaitement :

  int str[] = {'h', 'e', 'l', 'l', 'o', '\0' };

  for(i=0; i<6; i++)
  {
    printf("%c", str[i]);
  }

Il faut savoir que les caractères et les chaînes de caractères ne sont que des chiffres, comme tout ce qui se trouve dans l'ordinateur. Lorsque vous écrivez 'a' dans le code source, il est prétraité pour devenir le nombre 97, qui est une constante entière.

Ainsi, si vous écrivez une expression comme

char ch = '5';
ch = ch - '0';

ceci est en fait équivalent à

char ch = (int)53;
ch = ch - (int)48;

qui passe ensuite par les promotions d'entiers du langage C

ch = (int)ch - (int)48;

et ensuite tronqué en un caractère pour s'adapter au type de résultat

ch = (char)( (int)ch - (int)48 );

Il y a beaucoup de choses subtiles comme ça qui se passent entre les lignes, où char est implicitement traité comme un int.

0 votes

Puisque la question n'est pas étiquetée avec ascii vous ne devez pas présumer d'un encodage spécifique. Réglage de char égal à int8_t est erronée car elle pourrait tout aussi bien être uint8_t o uint24_t .

3 votes

@RolandIllig Non, un char est toujours de 1 octet et si les types int8_t / uint8_t existent sur le système donné (ce qui est très probable), ils seront en mesure d'adapter le résultat d'une char car il sera alors de 8 bits. Sur des systèmes très exotiques comme divers DSP obsolètes, char sera de 16 bits et le uint8_t n'existera pas. Écrire du code pour la compatibilité avec des DSP obsolètes est un non-sens, tout comme écrire pour la compatibilité avec les systèmes de complément ou de signe et magnitude. Une énorme perte de temps, puisque ces systèmes n'existent pratiquement pas dans le monde réel.

20voto

Fred Nurk Points 8927

(Cette réponse concerne le côté C++ des choses, mais le problème de l'extension des signes existe aussi en C).

Manipuler les trois char types ( signed , unsigned y char ) est plus délicat qu'il n'y paraît au premier abord. Les valeurs comprises entre 0 et SCHAR_MAX (qui est de 127 pour un appareil 8-bit char ) sont faciles :

char c = somevalue;
signed char sc = c;
unsigned char uc = c;
int n = c;

Mais, quand somevalue est en dehors de cette plage, il ne passe que par unsigned char vous donne des résultats cohérents pour le "même" char dans les trois types :

char c = somevalue;
signed char sc = c;
unsigned char uc = c;
// Might not be true: int(c) == int(sc) and int(c) == int(uc).
int nc = (unsigned char)c;
int nsc = (unsigned char)sc;
int nuc = (unsigned char)uc;
// Always true: nc == nsc and nc == nuc.

Ceci est important lorsque vous utilisez des fonctions de ctype.h tels que isupper o toupper en raison de l'extension du signe :

char c = negative_char;  // Assuming CHAR_MIN < 0.
int n = c;
bool b = isupper(n);  // Undefined behavior.

Notez que la conversion en int est implicite ; ceci a le même UB :

char c = negative_char;
bool b = isupper(c);

Pour corriger cela, passez par unsigned char ce qui est facilement réalisable en enveloppant ctype.h fonctionne grâce à safe_ctype :

template<int (&F)(int)>
int safe_ctype(unsigned char c) { return F(c); }

//...
char c = CHAR_MIN;
bool b = safe_ctype<isupper>(c);  // No UB.

std::string s = "value that may contain negative chars; e.g. user input";
std::transform(s.begin(), s.end(), s.begin(), &safe_ctype<toupper>);
// Must wrap toupper to eliminate UB in this case, you can't cast
// to unsigned char because the function is called inside transform.

Cela fonctionne car toute fonction prenant l'un des trois types de caractères peut également prendre les deux autres types de caractères. Cela conduit à deux fonctions qui peuvent manipuler n'importe lequel des types :

int ord(char c) { return (unsigned char)c; }
char chr(int n) {
  assert(0 <= n);  // Or other error-/sanity-checking.
  assert(n <= UCHAR_MAX);
  return (unsigned char)n;
}

// Ord and chr are named to match similar functions in other languages
// and libraries.

ord(c) donne toujours une valeur non-négative, même si on lui passe une valeur négative. char ou négative signed char - et chr prend n'importe quelle valeur ord produit et rend exactement la même char .

Dans la pratique, je me contenterais probablement de faire un casting à travers unsigned char au lieu de les utiliser, mais ils enveloppent succinctement le casting, fournissent un endroit pratique pour ajouter la vérification d'erreur pour les int -to- char et seraient plus courtes et plus claires lorsque vous devez les utiliser plusieurs fois à proximité les unes des autres.

7voto

T.E.D. Points 26829

Cela dépend en quelque sorte de ce que vous entendez par "convertir".

Si vous avez une série de caractères qui représente un entier, comme "123456", il y a deux façons typiques de le faire en C : Utiliser une conversion spéciale comme atoi() o strtol() ou l'outil polyvalent sscanf() . C++ (qui est en réalité un langage différent se faisant passer pour une mise à niveau) en ajoute un troisième, les chaînes de caractères.

Si vous voulez dire que vous voulez le modèle exact de bit dans l'un de vos int à traiter comme une char c'est plus facile. En C, les différents types d'entiers sont plus un état d'esprit que de véritables "types" distincts. Commencez simplement à l'utiliser là où char sont demandées, et tout devrait bien se passer. Vous pourriez avoir besoin d'une conversion explicite pour que le compilateur cesse de se plaindre à l'occasion, mais tout ce que cela devrait faire est de laisser tomber tous les bits supplémentaires au-delà de 256.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X