Un caractère peut représenter une lettre, un chiffre ou simplement une unité de texte, tandis qu’un entier sert aux calculs et aux index. La conversion de char vers int devient donc délicate dès qu’il faut distinguer la valeur numérique d’un chiffre, le code du caractère et le code Unicode. Je présente ici les méthodes fiables en C, C++, Java et Python, avec les erreurs courantes à éviter.
L’essentiel pour convertir correctement un caractère en entier
-
Chiffre décimal : utilisez une conversion dédiée ou soustrayez le caractère
'0'. - Code du caractère : une conversion directe renvoie souvent une valeur de codage, pas la valeur mathématique attendue.
-
C et C++ : la promotion automatique vers
intest pratique, mais elle ne transforme pas'7'en7. -
Python : utilisez
int()pour un chiffre etord()pour son code Unicode. - Unicode : un caractère visuel peut nécessiter un traitement différent selon le langage et l’encodage.
Deux conversions qui n’ont pas le même résultat
Quand je lis '7', je vois le nombre sept. Le programme, lui, voit un caractère associé à une valeur de codage. La conversion attendue dépend donc de l’objectif : obtenir 7 pour effectuer un calcul, ou récupérer le code numérique correspondant à '7'.
| Objectif | Exemple | Résultat attendu |
|---|---|---|
| Valeur du chiffre | '7' |
7 |
| Code du caractère | 'A' |
Une valeur de codage, souvent 65 en ASCII |
| Code Unicode | 'é' |
Le point de code Unicode du caractère |
Le piège le plus fréquent consiste à appliquer un cast à '7' en pensant obtenir 7. En C ou en C++, un cast vers int donne généralement le code numérique du caractère, souvent 55 pour '7' en ASCII. Pour obtenir sa valeur décimale, il faut utiliser une logique adaptée aux chiffres.
La méthode fiable en C et en C++
Transformer un chiffre en valeur numérique
Pour un caractère garanti compris entre '0' et '9', la formule classique est simple :
char c = '7';
int valeur = c - '0';
Cette opération repose sur l’ordre consécutif des chiffres dans le jeu de caractères utilisé par les implémentations modernes. Elle produit 7, et non le code de '7'. Je l’utilise volontiers pour un parseur léger, à condition de vérifier la validité du caractère avant le calcul.
if (c >= '0' && c <= '9') {
int valeur = c - '0';
}
Pour une entrée non contrôlée, la bibliothèque standard offre une approche plus explicite avec std::isdigit en C++. Il faut toutefois convertir le caractère en unsigned char avant l’appel lorsque sa valeur peut être négative, sinon certains octets peuvent provoquer un comportement indéfini.
Obtenir le code du caractère
Si votre objectif est réellement de récupérer la valeur de codage, la conversion directe convient :
char c = 'A';
int code = static_cast(c);
En C++, la promotion vers int se produit souvent automatiquement dans une expression arithmétique. Je préfère néanmoins écrire le type de manière explicite lorsque le code manipule des octets, car cela rend l’intention claire et évite les surprises liées au type char, qui peut être signé ou non signé selon le compilateur.
Traiter plusieurs caractères
Un seul char ne contient qu’une unité de caractère. Pour convertir une chaîne comme "123" en entier, il faut utiliser une fonction de parsing telle que std::from_chars en C++ ou strtol en C. La soustraction de '0' ne concerne que la conversion d’un chiffre isolé.
int resultat = 0;
for (char c : texte) {
if (c < '0' || c > '9') {
// Entrée invalide
break;
}
resultat = resultat * 10 + (c - '0');
}
Cette boucle montre le mécanisme utilisé par un parseur rudimentaire. En production, je recommande une fonction standard capable de signaler les erreurs et les dépassements, surtout si la chaîne provient d’un formulaire, d’un fichier ou d’un flux réseau.
Ce qui change en Java
Java convertit automatiquement un char vers un int, mais le résultat représente la valeur UTF-16 de l’unité de code. Ainsi, (int) 'A' donne généralement 65, tandis que (int) '7' donne le code du caractère, pas le nombre 7.
char c = '7';
int code = (int) c; // code UTF-16 du caractère
int valeur = c - '0'; // 7, si c est bien un chiffre
Pour accepter plusieurs bases, Character.digit est souvent plus robuste. Il peut convertir un chiffre hexadécimal comme 'B' en valeur 11, ce que la simple soustraction de '0' ne permet pas.
int valeur = Character.digit('B', 16); // 11
La différence devient importante avec les caractères Unicode situés hors du plan multilingue de base. En Java, un char est une unité UTF-16 de 16 bits, alors qu’un véritable point de code Unicode peut nécessiter deux unités. Pour traiter correctement ces caractères, il faut utiliser les méthodes dédiées aux points de code plutôt qu’un simple cast.
La bonne approche en Python et en JavaScript
Python
Python ne possède pas de type char distinct. Un caractère est une chaîne de longueur 1, ce qui rend la distinction particulièrement lisible :
c = '7'
valeur = int(c) # 7
code = ord(c) # code Unicode du caractère
int('7') transforme le texte en nombre et lève une exception si le contenu n’est pas convertible. ord('A'), de son côté, renvoie le point de code Unicode. Pour une saisie utilisateur, je préfère intercepter ValueError plutôt que de supposer que l’entrée contient toujours un chiffre valide.
try:
valeur = int(c)
except ValueError:
valeur = None
Lire aussi : Convertir string en date - Évitez les bugs en production
JavaScript
En JavaScript, un caractère est également une chaîne. Pour un chiffre simple, Number(c) est généralement le choix le plus direct :
const c = '7';
const valeur = Number(c); // 7
const code = c.codePointAt(0); // point de code Unicode
Attention à parseInt : cette fonction peut accepter le début numérique d’une chaîne plus longue, comme "12px". Pour valider une valeur composée uniquement d’un chiffre, je trouve Number.isInteger(Number(c)) plus explicite, complété par un contrôle de longueur si nécessaire.
Les erreurs qui produisent des résultats trompeurs
La première erreur est de confondre représentation textuelle et valeur numérique. Le caractère '4' n’est pas l’entier 4, même si les deux affichages se ressemblent. Un cast change parfois le type sans effectuer la conversion sémantique attendue.
-
Utiliser un cast seul pour convertir
'9'en 9. -
Oublier la validation avant de soustraire
'0'. - Traiter une chaîne comme un caractère unique.
- Négliger Unicode lorsqu’une entrée peut contenir des caractères non ASCII.
- Ignorer les dépassements lors de la conversion d’un nombre composé de plusieurs chiffres.
Un autre problème courant apparaît avec les caractères accentués et les octets UTF-8. En C, parcourir une chaîne octet par octet ne signifie pas forcément parcourir ses caractères visuels. Pour une application internationale, il faut choisir consciemment entre manipulation d’octets, d’unités de code et de points de code.
Je conseille aussi de tester les bornes plutôt qu’un seul cas heureux. Vérifiez au minimum '0', '9', un caractère alphabétique, une chaîne vide et un caractère accentué si votre programme accepte du texte utilisateur.
Choisir la méthode selon le besoin réel
La meilleure solution dépend moins du langage que de la question posée au programme. Le tableau suivant permet de trancher rapidement :
| Besoin | Méthode recommandée | Point de vigilance |
|---|---|---|
| Chiffre ASCII unique en C/C++ | c - '0' |
Valider l’intervalle '0' à '9'
|
| Chiffre avec base en Java | Character.digit |
Retourne une valeur négative si le caractère est invalide |
| Caractère Python vers nombre | int(c) |
Gérer ValueError
|
| Code Unicode |
ord, codePointAt ou équivalent |
Ne pas confondre code et valeur décimale |
| Chaîne numérique complète | Fonction de parsing standard | Contrôler format, signe et dépassement |
Dans un exercice simple, la conversion directe d’un chiffre suffit. Dans un logiciel qui traite des données externes, je privilégie toujours une fonction de parsing avec un résultat d’erreur clair. Quelques lignes de validation évitent alors des bugs difficiles à repérer dans les calculs ou les index de tableaux.
Le réflexe à conserver pour chaque conversion
Avant de convertir, je pose une seule question : est-ce que je veux la valeur du chiffre ou le code du caractère ? Pour '8', la première réponse donne 8, tandis que la seconde donne sa valeur de codage. Cette distinction règle la majorité des erreurs liées au passage d’un caractère à un entier.
Pour finir, limitez la conversion directe aux cas maîtrisés, validez les entrées externes et traitez Unicode avec les outils prévus par le langage. Cette petite discipline rend le code plus fiable, plus lisible et bien plus facile à faire évoluer.