Conversion de Char en int en C

Si je veux convertir un seul caractère numérique en valeur numérique, par exemple, si:

 char c = '5'; 

et je veux que c tienne 5 au lieu de '5' , est-ce 100% portable comme ça?

 c = c - '0'; 

J’ai entendu dire que tous les jeux de caractères stockent les numéros dans un ordre consécutif, donc je suppose, mais j’aimerais savoir s’il existe une fonction de bibliothèque organisée pour effectuer cette conversion et comment procéder de manière conventionnelle. Je suis un vrai débutant 🙂

Oui, c’est une conversion en toute sécurité. C exige que cela fonctionne. Cette garantie figure à la section 5.2.1, paragraphe 2, de la dernière norme ISO C, dont le projet récent est N1570 :

Les jeux de caractères source et d’exécution de base doivent avoir les membres suivants:
[…]
les 10 chiffres décimaux
0 1 2 3 4 5 6 7 8 9
[…]
Dans les jeux de caractères source et d’exécution de base, la valeur de chaque caractère après 0 dans la liste de chiffres décimaux ci-dessus doit être supérieure de un à la valeur du précédent.

Les codes ASCII et EBCDIC, ainsi que les jeux de caractères dérivés de ceux-ci, satisfont à cette exigence, raison pour laquelle le standard C a pu l’imposer. Notez que les lettres ne sont pas contiguës dans EBCDIC et que C n’en a pas besoin.

Il n’y a pas de fonction de bibliothèque pour le faire pour un seul caractère, vous devez d’abord créer une chaîne:

 int digit_to_int(char d) { char str[2]; str[0] = d; str[1] = '\0'; return (int) strtol(str, NULL, 10); } 

Vous pouvez également utiliser la fonction atoi() pour effectuer la conversion, une fois que vous avez une chaîne, mais strtol() est meilleur et plus sûr.

Comme les commentateurs l’ont souligné, il est extrêmement excessif d’appeler une fonction pour effectuer cette conversion; votre approche initiale pour soustraire «0» est la bonne façon de faire cela. Je voulais simplement montrer comment l’approche standard recommandée consistant à convertir un nombre sous forme de chaîne en un nombre “vrai” serait utilisée, ici.

Essaye ça :

 char c = '5' - '0'; 
 int i = c - '0'; 

Vous devez savoir que cela n’effectue aucune validation sur le caractère – par exemple, si le caractère était ‘a’, vous obtiendriez 91 – 48 = 49. Surtout si vous avez affaire à une entrée utilisateur ou réseau, vous devriez probablement effectuez la validation pour éviter les mauvais comportements dans votre programme. Il suffit de vérifier la plage:

 if ('0' <= c && c <= '9') { i = c - '0'; } else { /* handle error */ } 

Notez que si vous souhaitez que votre conversion traite les chiffres hexadécimaux, vous pouvez vérifier la plage et effectuer le calcul approprié.

 if ('0' <= c && c <= '9') { i = c - '0'; } else if ('a' <= c && c <= 'f') { i = 10 + c - 'a'; } else if ('A' <= c && c <= 'F') { i = 10 + c - 'A'; } else { /* handle error */ } 

Cela convertira un seul caractère hexadécimal, indépendant des majuscules ou des minuscules, en un entier.

Vous pouvez utiliser atoi , qui fait partie de la bibliothèque standard.

Comme vous ne convertissez qu’un seul caractère, la fonction atoi () est excessive. atoi () est utile si vous convertissez des représentations sous forme de chaîne de nombres. Les autres posts en ont donné des exemples. Si je lis votre message correctement, vous ne convertissez qu’un seul caractère numérique. Donc, vous allez seulement convertir un caractère compris entre 0 et 9. Dans le cas où vous ne convertissez qu’un seul caractère numérique, votre suggestion de soustraire “0” vous donnera le résultat souhaité. La raison pour laquelle cela fonctionne est que les valeurs ASCII sont consécutives (comme vous l’avez dit). Donc, soustraire la valeur ASCII de 0 (valeur ASCII 48 – voir Tableau ASCII pour les valeurs) d’un caractère numérique donnera la valeur du nombre. Donc, votre exemple de c = c – ‘0’ où c = ‘5’, ce qui se passe réellement est 53 (la valeur ASCII de 5) – 48 (la valeur ASCII de 0) = 5.

Lorsque j’ai posté cette réponse pour la première fois, je n’ai pas pris en compte votre commentaire selon lequel vous pouviez être 100% portable entre différents jeux de caractères. J’ai fait quelques recherches plus poussées et il semble que votre réponse soit encore généralement correcte. Le problème est que vous utilisez un caractère qui est un type de données 8 bits. Ce qui ne fonctionnerait pas avec tous les types de caractères. Lisez cet article de Joel Spolsky sur Unicode pour plus d’informations sur Unicode. Dans cet article, il dit qu’il utilise wchar_t pour les caractères. Cela a bien fonctionné pour lui et il publie son site Web dans 29 langues. Donc, vous devrez changer votre caractère en wchar_t. Autre que cela, il dit que le caractère sous la valeur 127 et ci-dessous sont fondamentalement les mêmes. Cela inclurait des caractères qui représentent des nombres. Cela signifie que les calculs de base que vous avez proposés devraient fonctionner pour ce que vous tentiez d’atteindre.

Oui. Ceci est sûr tant que vous utilisez des caractères ASCII standard, comme dans cet exemple.

Normalement, si rien ne garantit que votre saisie se situe dans la plage “0” .. “9”, vous devez effectuer une vérification comme celle-ci:

 if (c >= '0' && c <= '9') { int v = c - '0'; // safely use v } 

Une alternative consiste à utiliser une table de recherche. Vous obtenez une vérification de plage simple et une conversion avec moins de code (et éventuellement plus rapide):

 // one-time setup of an array of 256 integers; // all slots set to -1 except for ones corresponding // to the numeric characters static const int CHAR_TO_NUMBER[] = { -1, -1, -1, ..., 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // '0'..'9' -1, -1, -1, ... }; // Now, all you need is: int v = CHAR_TO_NUMBER[c]; if (v != -1) { // safely use v } 

PS Je sais que c'est exagéré . Je voulais juste la présenter comme une solution alternative qui n’est peut-être pas immédiatement évidente.

Comme d’autres l’ont suggéré, mais enveloppés dans une fonction:

 int char_to_digit(char c) { return c - '0'; } 

Maintenant, utilisez simplement la fonction. Si, en bout de ligne, vous décidez d’utiliser une méthode différente, il vous suffit de modifier l’implémentation (performances, différences de jeu de caractères, etc.), vous n’aurez pas besoin de changer les appelants.

Cette version suppose que c contient un caractère représentant un chiffre. Vous pouvez vérifier cela avant d’appeler la fonction, en utilisant la fonction isdigit de ctype.h.

Puisque les codes ASCII pour “0”, “1”, “2” … sont placés de 48 à 57, ils sont essentiellement continus. Maintenant, les opérations arithmétiques nécessitent la conversion du type de données char en type de données int.Ce que vous êtes en train de faire est: 53-48 et stocke donc la valeur 5 avec laquelle vous pouvez effectuer des opérations sur un entier le compilateur ne donne aucune erreur mais effectue simplement une opération modulo 256 pour placer la valeur dans sa plage acceptable

Vous pouvez simplement utiliser la fonction atol() :

 #include  #include  int main() { const char *c = "5"; int d = atol(c); printf("%d\n", d); }