Comment convertir char en int?

124

Quelle est la bonne façon de convertir un charen int? Cela donne 49:

int val = Convert.ToInt32('1');
//int val = Int32.Parse("1"); // Works

Je ne veux pas convertir en chaîne et ensuite l'analyser.

tvr
la source
1
Reproduction possible de cette question.
RBT
Double

Réponses:

283

Je suis surpris que personne n'ait mentionné la méthode statique intégrée directement dans System.Char...

int val = (int)Char.GetNumericValue('8');
// val == 8
Joel Mueller
la source
18
Bon endroit! +1 Très étrange qu'il renvoie un double, cependant
Marc Gravell
4
Je suis d'accord, je ne comprends pas pourquoi il renvoie «double» - comment un seul caractère peut-il représenter un nombre à virgule flottante?
Joel Mueller
49
Il existe de nombreux caractères Unicode qui représentent un nombre non entier, par exemple U + 2153 .
dtb
26
@dtb - Je n'avais pas envisagé cela. Char.GetNumericValue('⅓')revient effectivement 0.3333.... Merci d'avoir fait remarquer cela!
Joel Mueller
1
Foot Note: cette fonction n'est actuellement pas disponible dans NetMF.
GisMofx
40

que diriez-vous (pour char c)

int i = (int)(c - '0');

qu'est-ce que la soustraction de la valeur char?

Re la question API (commentaires), peut-être une méthode d'extension?

public static class CharExtensions {
    public static int ParseInt32(this char value) {
        int i = (int)(value - '0');
        if (i < 0 || i > 9) throw new ArgumentOutOfRangeException("value");
        return i;
    }
}

puis utilisez int x = c.ParseInt32();

Marc Gravell
la source
1
J'aurais dû mentionner, je savais à ce sujet mais y a-t-il un autre moyen? Je voulais savoir s'il existe une API pour faire cela?
tvr
4
Si vous voulez un comportement similaire à int.Parse, c'est- à -dire qu'une exception est levée sur une entrée invalide, vous devrez ajouter une vérification de limites supplémentaires:if (i < 0 || i > 9) throw new FormatException();
Dirk Vollmar
@ user386338 J'ai bien peur qu'il n'y en ait pas.
Eugene Cheverda
@ user386338 - mis à jour avec une option concernant l' API, incluant également les commentaires de @ 0xA3
Marc Gravell
@ user386338 - voir la réponse de Joel pour une méthode API intégrée
Marc Gravell
21

Ce que tout le monde oublie, c'est d'expliquer POURQUOI cela se produit.

Un Char, est essentiellement un entier, mais avec un pointeur dans la table ASCII. Tous les caractères ont une valeur entière correspondante comme vous pouvez le voir clairement en essayant de l'analyser.

Pranay a clairement un jeu de caractères différent, c'est pourquoi son code ne fonctionne pas. le seul moyen est

int val = '1' - '0';

parce que cela recherche la valeur entière dans le tableau '0'dont est alors la «valeur de base» en soustrayant votre nombre au format char de cela vous donnera le nombre d'origine.

Stefanvds
la source
15
int i = (int)char.GetNumericValue(c);

Encore une autre option:

int i = c & 0x0f;

Cela devrait également accomplir cela.

Grif
la source
4
int val = '1' - '0';

Cela peut être fait en utilisant des codes ascii où '0' est le plus bas et le nombre de caractères compte à partir de là

Tristan
la source
C'est génial! imo la solution la plus élégante ici.
arabisoft
3
int val = '1' - 48;
x2.
la source
@Luke Xu: '0' a le code ASCII 0x30 qui est 48 en décimal donc c'est la même chose que '1' - '0'
NiKiZe
3

Vous pouvez utiliser la méthode d'extension suivante:

public static class CharExtensions
    {
        public static int CharToInt(this char c)
        {
            if (c < '0' || c > '9')
                throw new ArgumentException("The character should be a number", "c");

            return c - '0';
        }
    }
Eugène Cheverda
la source
1
@ 0xA3 Le contrôle de plage doit être au début de la méthode en général. Sémantiquement, si nous devons convertir charen, intnous devons vérifier la plage du paramètre d'entrée, pas la intvaleur de sortie .
Eugene Cheverda
Il n'est pas nécessaire de vérifier la intvaleur du résultat car la plage de caractères numériques a été effectuée au début de la méthode, il y aura donc une valeur résultante correcte, si le caractère spécifié n'est pas dans la plage de caractères numériques, une exception sera levée. La même logique que vous avez fournie mais la vérification de la plage est effectuée au début de la méthode.
Eugene Cheverda
Désolé, j'ai mal lu votre exemple de code. Parfois, il est difficile de voir les choses les plus évidentes. Je parie que le code disait if (c < 0 || c > 9)...
Dirk Vollmar
1

Le moyen le plus sûr d'y parvenir consiste à utiliser la méthode Int32.TryParse. Voir ici: http://dotnetperls.com/int-tryparse

MUG4N
la source
TryParse est pour les chaînes pas pour les caractères
tvr
Oui, mais c'est toujours le moyen le plus sûr d'accomplir la conversion
MUG4N
1
La conversion d'un seul caractère en entier est-elle une question de sécurité?
Joel Mueller
1
«Sécurisé» dans ce cas signifie que cela ne posera pas de problèmes si votre caractère n'est pas réellement un nombre ascii - il peut s'agir d'un caractère Unicode multi-octets.
Robin Bennett
1
int val = '1' & 15;

Le binaire des caractères ASCII 0-9 est:

0 - 00110000

1 - 00110001

2 - 00110010

3 - 00110011

4 - 00110100

5 - 00110101

6 - 00110110

7 - 00110111

8 - 00111000

9 - 00111001

et si vous prenez dans chacun d'eux les 4 premiers LSB (en utilisant ET au niveau du bit avec 8'b00001111 qui équivaut à 15), vous obtenez le nombre réel (0000 = 0,0001 = 1,0010 = 2, ...)

Tomer Wolberg
la source
Comment cela fonctionne-t-il en termes de types? vous utilisez un opérateur binaire entre un char et un int, puis retournez un int? Le AND logique utilise-t-il la représentation binaire du char et de l'int et renvoie-t-il une représentation binaire, puis lorsque vous définissez le var comme un int, il utilise cette représentation?
mitomed le
@mitnomed yes et si vous utilisez byte par exemple, alors il utilise la représentation byte.
Tomer Wolberg
0

Vous pouvez essayer quelque chose comme ceci:

int val = Convert.ToInt32("" + '1');
briba
la source
pourquoi pas simplement .ToString ()?
Veikedo
@Veikedo il veut un int, et non une chaîne.
briba
6
Je veux direConvert.ToInt32('1'.ToString())
Veikedo
0

Une extension de quelques autres réponses qui couvre la représentation hexadécimale:

public int CharToInt(char c) 
{
    if (c >= '0' && c <= '9') 
    {
        return c - '0';
    }
    else if (c >= 'a' && c <= 'f') 
    {
        return 10 + c - 'a';
    }
    else if (c >= 'A' && c <= 'F') 
    {
        return 10 + c - 'A';
    }

    return -1;
}
Oleksandr Lytvyn
la source