@Matt: ce serait une bonne idée d'être plus concret. poser des questions sur une généralisation invite simplement à des réponses généralisées qui ne sont pas applicables ou même correctes pour votre tâche. Gardez à l'esprit que lorsque vous devez demander, vous n'en savez probablement pas assez pour généraliser correctement.
Bravo et hth. - Alf
@Alf P. Steinbach: La question initiale était vague concernant la langue. Avec les mots c- clés et c++, je pense que les réponses face aux deux langues sont raisonnables.
Matt Joiner
8
D'après ma vaste expérience sur d'autres forums techniques, mon intuition est que l'OP signifie vraiment "comment puis-je prendre la représentation textuelle d'un nombre (en base 10) et le convertir en nombre correspondant?" De manière générale, les néophytes C et C ++ ont généralement des idées incroyablement floues sur le fonctionnement du texte dans ces langages et ce que charcela signifie vraiment.
Karl Knechtel
3
@KarlKnechtel: Si c'est vrai (je lui donne environ 50/50 car de nombreux premiers tutoriels encouragent également à obtenir des valeurs ASCII à partir des caractères, même si ASCII ne couvre pas toute la plage), l'OP doit être clair - mais c'est une dupe de stackoverflow.com/questions/439573/… .
Fred Nurk
3
Le PO avait trois heures pour clarifier cette question et ne l'a pas fait. En l'état, il n'y a aucun moyen de savoir ce qui est réellement demandé. A voté pour fermer.
sbi
Réponses:
552
Ça dépend de ce que tu veux faire:
pour lire la valeur sous forme de 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' -> 1etc, 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 0vient juste avant 1dans le tableau ascii (et ainsi de suite jusqu'à 9), la différence entre les deux donne le nombre que le caractère areprésente.
@KshitijBanerjee Ce n'est pas une bonne idée pour deux raisons: il 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)
SheetJS
2
int ia = a - '0' - c'est ce dont vous avez besoin
funk
5
@ kevin001 Si vous souhaitez convertir le caractère en int et qu'un caractère '1'fournit un nombre ascii qui ne l'est pas 1, vous devez supprimer le décalage '0'pour le réaligner pour qu'il compte de 0 à 9. Les nombres consécutifs 1-9 sont adjacents dans le nombre entier ascii.
krisdestruction
Aucun casting n'est requis / souhaité
Craig Estey
97
Eh bien, en code ASCII, les chiffres (chiffres) commencent à 48 . Il vous suffit de:
@chad: Non seulement plus lisible, mais aussi plus portable. C et C ++ ne garantissent pas une représentation ASCII, mais ils garantissent que quelle que soit la représentation utilisée, les représentations des 10 chiffres décimaux sont contiguës et dans l'ordre numérique.
Ben Voigt
La seule chose que j'aurais changé est d'avoir 48 ans, ce qui semble un peu "magique" à'0'
ArielGro
59
C et C ++ promeuvent toujours les types au moins int. De plus, les littéraux de caractères sont de type inten C et charen C ++.
Vous pouvez convertir un chartype simplement en l'attribuant à un int.
Vous pouvez également utiliser l' unaire très sous-estimé operator+()à cette fin.
Cubbi
24
-1 La réponse est incorrecte pour la seule interprétation significative de la question. Ce (code int a = c;) conservera toutes les valeurs négatives que les fonctions de bibliothèque standard C ne peuvent pas gérer. Les fonctions de bibliothèque standard C définissent la norme pour ce que signifie gérer les charvaleurs en tant que int.
Bravo et hth. - Alf
6
@Matt: Je garde le downvote. Je le renforcerais si possible! L'interprétation de la question que vous et d'autres avez supposée n'est pas significative, car elle est trop triviale, et parce que pour la combinaison particulière de types du PO, il y a un problème pratique très important pas si trivial. Les conseils que vous donnez sont directement dangereux pour le novice. Il en résultera très probablement un comportement indéfini pour leurs programmes qui utilisent les fonctions de classification des caractères de la bibliothèque C standard. Re ref. à la réponse de @ Sayam, il a supprimé cette réponse.
Bravo et hth. - Alf
3
-1 pour être incorrect: isupper () aura des résultats indéfinis s'il passe un caractère 1252 highbit.
Chris Becke
1
Qu'entendez-vous par «toujours promouvoir»? Les valeurs sont promues pendant les conversions implicites, certains types de paramètres passant (par exemple, à une fonction varargs), et lorsqu'un opérateur doit rendre ses opérandes compatibles avec les types. Mais il y a certainement des moments où une valeur n'est pas promue (comme si je passe un char à une fonction qui attend un char), sinon nous n'aurions pas de types plus petits qu'un int.
Adrian McCarthy
31
char n'est qu'un entier de 1 octet. Il n'y a rien de magique avec le type char! Tout comme vous pouvez attribuer 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 se trouve être "char", ce qui laisse entendre qu'il ne doit contenir que des caractères. Mais en réalité, "char" est juste un mauvais choix pour confondre tous ceux qui essaient d'apprendre la langue. Un meilleur nom est int8_t, et vous pouvez utiliser ce nom à la place, si votre compilateur suit la dernière norme C.
Bien que vous sûr devez utiliser le type char lorsque vous effectuez la gestion des chaînes, car l'index des ajustements de table ASCII classique dans 1 octet. Cependant, vous pouvez également manipuler des cordes avec des entiers réguliers, bien qu'il n'y ait aucune raison pratique dans le monde réel pour laquelle vous voudriez faire cela. 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]);}
Vous devez comprendre que les caractères et les chaînes ne sont que des nombres, comme tout le reste de l'ordinateur. Lorsque vous écrivez «a» dans le code source, il est prétraité en nombre 97, qui est une constante entière.
Donc, si vous écrivez une expression comme
char ch ='5';
ch = ch -'0';
c'est en fait équivalent à
char ch =(int)53;
ch = ch -(int)48;
qui passe ensuite par les promotions entières du langage C
ch =(int)ch -(int)48;
puis tronqué à 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 entre les lignes, où char est implicitement traité comme un int.
Étant donné que la question n'est pas balisée ascii, vous ne devez pas supposer d'encodage spécifique. La valeur charégale à int8_test incorrecte, car elle pourrait également être uint8_tou uint24_t.
Roland Illig
1
@RolandIllig Non, a charvaut toujours 1 octet et si les types int8_t/ uint8_texistent sur le système donné (ce qui est très probable), ils pourront ajuster le résultat de a char, car ce sera alors 8 bits. Sur les systèmes très exotiques tels que divers DSP obsolètes, charsera de 16 bits et uint8_tn'existera pas. Écrire du code pour la compatibilité avec les DSP obsolètes est un non-sens, tout comme l'écrire pour la compatibilité avec ses systèmes de complément ou de signe et d'amplitude. Énorme perte de temps, car de tels systèmes existent à peine dans le monde réel.
Lundin
18
(Cette réponse concerne le côté C ++ des choses, mais le problème d'extension de signe existe également en C.)
Manipulation des trois chartypes ( signed, unsignedet char) est plus délicate qu'il n'y paraît. Les valeurs comprises entre 0 et SCHAR_MAX(qui est de 127 pour un 8 bits char) sont faciles:
char c = somevalue;signedchar sc = c;unsignedchar uc = c;int n = c;
Mais, lorsque se somevaluesitue en dehors de cette plage, le simple unsigned charfait de vous donner des résultats cohérents pour les "mêmes" charvaleurs dans les trois types:
char c = somevalue;signedchar sc = c;unsignedchar uc = c;// Might not be true: int(c) == int(sc) and int(c) == int(uc).int nc =(unsignedchar)c;int nsc =(unsignedchar)sc;int nuc =(unsignedchar)uc;// Always true: nc == nsc and nc == nuc.
Ceci est important lorsque vous utilisez des fonctions de ctype.h , telles que isupperou toupper, en raison de l'extension de signe:
char c = negative_char;// Assuming CHAR_MIN < 0.int n = c;bool b = isupper(n);// Undefined behavior.
Notez que la conversion via int est implicite; cela a le même UB:
char c = negative_char;bool b = isupper(c);
Pour résoudre ce problème, passez par unsigned char, ce qui se fait facilement en encapsulant les fonctions ctype.h via safe_ctype :
template<int(&F)(int)>int safe_ctype(unsignedchar 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. Il conduit à deux fonctions qui peuvent gérer n'importe lequel des types:
int ord(char c){return(unsignedchar)c;}char chr(int n){assert(0<= n);// Or other error-/sanity-checking.assert(n <= UCHAR_MAX);return(unsignedchar)n;}// Ord and chr are named to match similar functions in other languages// and libraries.
ord(c)vous donne toujours une valeur non négative - même en cas de passage négatif charou négatif signed char- et chrprend n'importe quelle valeur ordproduit et rend exactement la même chose char.
Dans la pratique, je ferais probablement un cast au unsigned charlieu de les utiliser, mais ils enveloppent succinctement le cast, fournissent un endroit pratique pour ajouter la vérification des erreurs pour int-to- char, et seraient plus courts et plus clairs lorsque vous devez les utiliser plusieurs fois à proximité.
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 existe deux façons typiques de le faire en C: Utilisez une conversion à usage spécial comme atoi () ou strtol () , ou le sscanf à usage général () . C ++ (qui est vraiment un langage différent se faisant passer pour une mise à niveau) ajoute un troisième, les flux de chaînes.
Si vous voulez dire que vous voulez que le motif de bits exact dans l'une de vos intvariables soit traité comme un char, c'est plus facile. En C, les différents types entiers sont vraiment plus un état d'esprit que de véritables "types" séparés. Commencez simplement à l'utiliser là où charon vous le demande, et ça devrait aller. Vous devrez peut-être une conversion explicite pour que le compilateur arrête de pleurnicher à l'occasion, mais tout ce qui devrait faire est de supprimer tous les bits supplémentaires au-delà de 256.
J'ai absolument des nullcompétences en C, mais pour une analyse simple:
char* something ="123456";int number = parseInt(something);
... cela a fonctionné pour moi:
int parseInt(char* chars){int sum =0;int len = strlen(chars);for(int x =0; x < len; x++){int n = chars[len -(x +1)]-'0';
sum = sum + powInt(n, x);}return sum;}int powInt(int x,int y){for(int i =0; i < y; i++){
x *=10;}return x;}
Ce code invoque rapidement un comportement indéfini et n'est donc pas adapté au copier-coller. (débordement int)
Roland Illig
4
Vraisemblablement, vous voulez cette conversion pour utiliser les fonctions de la bibliothèque standard C.
Dans ce cas, faites (syntaxe C ++)
typedefunsignedcharUChar;char myCppFunc(char c ){returnchar( someCFunc(UChar( c )));}
L'expression est UChar( c )convertie unsigned charen afin de se débarrasser des valeurs négatives qui, à l'exception d'EOF, ne sont pas prises en charge par les fonctions C.
Ensuite, le résultat de cette expression est utilisé comme argument réel pour un intargument formel. Où vous obtenez une promotion automatique int. Vous pouvez également écrire cette dernière étape explicitement, comme int( UChar( c ) ), mais personnellement, je trouve cela trop verbeux.
J'avais des problèmes pour convertir un tableau de caractères comme "7c7c7d7d7d7d7c7c7c7d7d7d7d7c7c7c7c7c7c7d7d7c7c7c7c7d7c7d7d7d7c7c2e2e2e"dans sa valeur entière réelle qui pourrait être représentée par `7C 'comme une valeur hexadécimale. Donc, après avoir cherché de l'aide, j'ai créé cela et j'ai pensé que ce serait cool de partager.
Cela sépare la chaîne de caractères en ses entiers droits, et peut être utile à plus de gens que moi;)
Avez-vous déjà testé ce code? Le 50 doit être un 48, le 55 ne fonctionne que pour les lettres ASCII majuscules tandis que votre exemple contient des lettres minuscules.
Roland Illig
0
Pour char ou short to int, il vous suffit d'attribuer la valeur.
c
- clés etc++
, je pense que les réponses face aux deux langues sont raisonnables.char
cela signifie vraiment.Réponses:
Ça dépend de ce que tu veux faire:
pour lire la valeur sous forme de code ascii, vous pouvez écrire
pour convertir le caractère
'0' -> 0
,'1' -> 1
etc, vous pouvez écrireExplication :
a - '0'
est équivalent à((int)a) - ((int)'0')
, ce qui signifie que les valeurs ascii des caractères sont soustraites les unes des autres. Puisque0
vient juste avant1
dans le tableau ascii (et ainsi de suite jusqu'à9
), la différence entre les deux donne le nombre que le caractèrea
représente.la source
&
-> -10), et il vous donne des nombres supérieurs à 10 (commex
-> 26)'1'
fournit un nombre ascii qui ne l'est pas1
, vous devez supprimer le décalage'0'
pour le réaligner pour qu'il compte de 0 à 9. Les nombres consécutifs 1-9 sont adjacents dans le nombre entier ascii.Eh bien, en code ASCII, les chiffres (chiffres) commencent à 48 . Il vous suffit de:
la source
'0'
C et C ++ promeuvent toujours les types au moins
int
. De plus, les littéraux de caractères sont de typeint
en C etchar
en C ++.Vous pouvez convertir un
char
type simplement en l'attribuant à unint
.la source
operator+()
à cette fin.int a = c;
) conservera toutes les valeurs négatives que les fonctions de bibliothèque standard C ne peuvent pas gérer. Les fonctions de bibliothèque standard C définissent la norme pour ce que signifie gérer leschar
valeurs en tant queint
.char n'est qu'un entier de 1 octet. Il n'y a rien de magique avec le type char! Tout comme vous pouvez attribuer 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 se trouve être "char", ce qui laisse entendre qu'il ne doit contenir que des caractères. Mais en réalité, "char" est juste un mauvais choix pour confondre tous ceux qui essaient d'apprendre la langue. Un meilleur nom est int8_t, et vous pouvez utiliser ce nom à la place, si votre compilateur suit la dernière norme C.
Bien que vous sûr devez utiliser le type char lorsque vous effectuez la gestion des chaînes, car l'index des ajustements de table ASCII classique dans 1 octet. Cependant, vous pouvez également manipuler des cordes avec des entiers réguliers, bien qu'il n'y ait aucune raison pratique dans le monde réel pour laquelle vous voudriez faire cela. Par exemple, le code suivant fonctionnera parfaitement:
Vous devez comprendre que les caractères et les chaînes ne sont que des nombres, comme tout le reste de l'ordinateur. Lorsque vous écrivez «a» dans le code source, il est prétraité en nombre 97, qui est une constante entière.
Donc, si vous écrivez une expression comme
c'est en fait équivalent à
qui passe ensuite par les promotions entières du langage C
puis tronqué à un caractère pour s'adapter au type de résultat
Il y a beaucoup de choses subtiles comme ça entre les lignes, où char est implicitement traité comme un int.
la source
ascii
, vous ne devez pas supposer d'encodage spécifique. La valeurchar
égale àint8_t
est incorrecte, car elle pourrait également êtreuint8_t
ouuint24_t
.char
vaut toujours 1 octet et si les typesint8_t
/uint8_t
existent sur le système donné (ce qui est très probable), ils pourront ajuster le résultat de achar
, car ce sera alors 8 bits. Sur les systèmes très exotiques tels que divers DSP obsolètes,char
sera de 16 bits etuint8_t
n'existera pas. Écrire du code pour la compatibilité avec les DSP obsolètes est un non-sens, tout comme l'écrire pour la compatibilité avec ses systèmes de complément ou de signe et d'amplitude. Énorme perte de temps, car de tels systèmes existent à peine dans le monde réel.(Cette réponse concerne le côté C ++ des choses, mais le problème d'extension de signe existe également en C.)
Manipulation des trois
char
types (signed
,unsigned
etchar
) est plus délicate qu'il n'y paraît. Les valeurs comprises entre 0 etSCHAR_MAX
(qui est de 127 pour un 8 bitschar
) sont faciles:Mais, lorsque se
somevalue
situe en dehors de cette plage, le simpleunsigned char
fait de vous donner des résultats cohérents pour les "mêmes"char
valeurs dans les trois types:Ceci est important lorsque vous utilisez des fonctions de ctype.h , telles que
isupper
outoupper
, en raison de l'extension de signe:Notez que la conversion via int est implicite; cela a le même UB:
Pour résoudre ce problème, passez par
unsigned char
, ce qui se fait facilement en encapsulant les fonctions ctype.h via safe_ctype :Cela fonctionne car toute fonction prenant l'un des trois types de caractères peut également prendre les deux autres types de caractères. Il conduit à deux fonctions qui peuvent gérer n'importe lequel des types:
ord(c)
vous donne toujours une valeur non négative - même en cas de passage négatifchar
ou négatifsigned char
- etchr
prend n'importe quelle valeurord
produit et rend exactement la même chosechar
.Dans la pratique, je ferais probablement un cast au
unsigned char
lieu de les utiliser, mais ils enveloppent succinctement le cast, fournissent un endroit pratique pour ajouter la vérification des erreurs pourint
-to-char
, et seraient plus courts et plus clairs lorsque vous devez les utiliser plusieurs fois à proximité.la source
Utilisation
static_cast<int>
:Edit: Vous devriez probablement essayer d'éviter d'utiliser
(int)
consultez Pourquoi utiliser static_cast <int> (x) au lieu de (int) x? pour plus d'informations.
la source
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 existe deux façons typiques de le faire en C: Utilisez une conversion à usage spécial comme atoi () ou strtol () , ou le sscanf à usage général () . C ++ (qui est vraiment un langage différent se faisant passer pour une mise à niveau) ajoute un troisième, les flux de chaînes.
Si vous voulez dire que vous voulez que le motif de bits exact dans l'une de vos
int
variables soit traité comme unchar
, c'est plus facile. En C, les différents types entiers sont vraiment plus un état d'esprit que de véritables "types" séparés. Commencez simplement à l'utiliser là oùchar
on vous le demande, et ça devrait aller. Vous devrez peut-être une conversion explicite pour que le compilateur arrête de pleurnicher à l'occasion, mais tout ce qui devrait faire est de supprimer tous les bits supplémentaires au-delà de 256.la source
J'ai absolument des
null
compétences en C, mais pour une analyse simple:... cela a fonctionné pour moi:
la source
Vraisemblablement, vous voulez cette conversion pour utiliser les fonctions de la bibliothèque standard C.
Dans ce cas, faites (syntaxe C ++)
L'expression est
UChar( c )
convertieunsigned char
en afin de se débarrasser des valeurs négatives qui, à l'exception d'EOF, ne sont pas prises en charge par les fonctions C.Ensuite, le résultat de cette expression est utilisé comme argument réel pour un
int
argument formel. Où vous obtenez une promotion automatiqueint
. Vous pouvez également écrire cette dernière étape explicitement, commeint( UChar( c ) )
, mais personnellement, je trouve cela trop verbeux.Santé et hth.,
la source
J'avais des problèmes pour convertir un tableau de caractères comme
"7c7c7d7d7d7d7c7c7c7d7d7d7d7c7c7c7c7c7c7d7d7c7c7c7c7d7c7d7d7d7c7c2e2e2e"
dans sa valeur entière réelle qui pourrait être représentée par `7C 'comme une valeur hexadécimale. Donc, après avoir cherché de l'aide, j'ai créé cela et j'ai pensé que ce serait cool de partager.Cela sépare la chaîne de caractères en ses entiers droits, et peut être utile à plus de gens que moi;)
J'espère que cela aide!
la source
Pour char ou short to int, il vous suffit d'attribuer la valeur.
Identique à int64.
Toutes les valeurs seront 16.
la source
Vous pouvez utiliser cette méthode atoi pour convertir char en int. Pour plus d'informations, vous pouvez vous référer à ce http://www.cplusplus.com/reference/cstdlib/atoi/ , http://www.cplusplus.com/reference/string/stoi/ .
la source