Come convertire char in int?


124

Qual è il modo corretto per convertire a charin int? Questo dà 49:

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

Non voglio convertirlo in stringa e poi analizzarlo.


1
Possibile duplicato di questa domanda.
RBT

Possibile duplicato di Convert char to int in C #
GSerg

Risposte:


283

Sono sorpreso che nessuno abbia menzionato il metodo statico integrato proprio in System.Char...

int val = (int)Char.GetNumericValue('8');
// val == 8

18
Buon posto! +1 Molto strano che restituisca un double, però
Marc Gravell

4
Sono d'accordo, non riesco a capire perché restituisce "doppio": come può un singolo carattere rappresentare un numero in virgola mobile?
Joel Mueller

49
Esistono molti caratteri Unicode che rappresentano un numero non intero, ad esempio U + 2153 .
dtb

26
@dtb - Non l'avevo considerato. Char.GetNumericValue('⅓')effettivamente ritorna 0.3333.... Grazie per la segnalazione!
Joel Mueller

1
Nota: questa funzione non è attualmente disponibile in NetMF.
GisMofx

40

che ne dici (per char c)

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

quale sottrazione del valore char?

Re la domanda API (commenti), forse un metodo di estensione?

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;
    }
}

quindi utilizzare int x = c.ParseInt32();


1
Avrei dovuto menzionarlo, lo sapevo, ma c'è un altro modo? Volevo sapere se esiste un'API per farlo?
tvr

4
Se si desidera un comportamento simile a int.Parse, ovvero che venga generata un'eccezione su un input non valido, è necessario aggiungere ulteriori limiti controllando:if (i < 0 || i > 9) throw new FormatException();
Dirk Vollmar

@ user386338 Temo che non ci sia.
Eugene Cheverda

@ user386338 - aggiornato con una nuova API di un'opzione, anche comprensivo di @ Feedback del 0xA3
Marc Gravell

@ user386338 - vedi la risposta di Joel per un metodo API integrato
Marc Gravell

21

Quello che tutti dimenticano è spiegare PERCHÉ questo accade.

Un Char, è fondamentalmente un numero intero, ma con un puntatore nella tabella ASCII. Tutti i caratteri hanno un valore intero corrispondente, come puoi vedere chiaramente quando provi ad analizzarlo.

Pranay ha chiaramente un set di caratteri diverso, ecco perché il suo codice non funziona. l'unico modo è

int val = '1' - '0';

perché questo cerca il valore intero nella tabella di '0'cui è quindi il 'valore di base' sottraendo il tuo numero in formato char da questo ti darà il numero originale.


15
int i = (int)char.GetNumericValue(c);

Ancora un'altra opzione:

int i = c & 0x0f;

Questo dovrebbe portare a termine anche questo.


4
int val = '1' - '0';

Questo può essere fatto usando codici ASCII dove '0' è il più basso e da lì i caratteri numerici vengono contati


È brillante! imo la soluzione più elegante qui.
arabisoft

3
int val = '1' - 48;

@Luke Xu: '0' ha il codice ASCII 0x30 che è 48 in decimale, quindi è lo stesso di '1' - '0'
NiKiZe

3

È possibile utilizzare il seguente metodo di estensione:

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';
        }
    }

1
@ 0xA3 Il controllo dell'intervallo deve essere all'inizio del metodo in generale. Semanticamente, se vogliamo convertire charin, intdobbiamo controllare l'intervallo del parametro di input, non il intvalore di output .
Eugene Cheverda

Non è necessario controllare il intvalore del risultato perché l'intervallo di caratteri numerici è stato eseguito all'inizio del metodo, quindi ci sarà un valore risultante corretto, se il carattere specificato non è compreso nell'intervallo di caratteri numerici, verrà generata un'eccezione. La stessa logica che hai fornito ma il controllo dell'intervallo viene eseguito all'inizio del metodo.
Eugene Cheverda

Mi spiace, ho letto male il tuo codice di esempio. A volte è difficile vedere le cose più ovvie. Scommetto che il codice dice if (c < 0 || c > 9)...
Dirk Vollmar

1

Il modo più sicuro per eseguire questa operazione è utilizzare il metodo Int32.TryParse. Vedi qui: http://dotnetperls.com/int-tryparse


TryParse è per le stringhe non per i caratteri
tvr

Sì, ma è ancora il modo più sicuro per eseguire la conversione
MUG4N

1
Convertire un singolo carattere in un intero è una questione di sicurezza?
Joel Mueller

1
"Sicuro" in questo caso significa che non causerà problemi se il tuo carattere non è effettivamente un numero ASCII - potrebbe essere un carattere Unicode multibyte.
Robin Bennett

1
int val = '1' & 15;

Il binario dei caratteri ASCII 0-9 è:

0 - 00110000

1 - 00110001

2 - 00110010

3 - 00110011

4 - 00110100

5 - 00110101

6 - 00110110

7 - 00110111

8 - 00111000

9 - 00111001

e se prendi in ognuno di essi i primi 4 LSB (usando AND bit per bit con 8'b00001111 che equivale a 15) ottieni il numero effettivo (0000 = 0,0001 = 1,0010 = 2, ...)


Come funziona in termini di tipi? stai usando un operatore bit per bit tra un carattere e un int e quindi restituisce un int? L'AND logico utilizza la rappresentazione binaria sia del carattere che dell'intensità e restituisce una rappresentazione binaria e quindi, poiché stai definendo la var come un int, utilizza quella rappresentazione?
mitomata il

@mitnomed yes e se usi byte, ad esempio, utilizza la rappresentazione in byte.
Tomer Wolberg il

0

Puoi provare qualcosa di simile:

int val = Convert.ToInt32("" + '1');

perché non solo .ToString ()?
Veikedo

@Veikedo vuole un int e non una stringa.
briba

6
Voglio direConvert.ToInt32('1'.ToString())
Veikedo

0

Un'estensione di alcune altre risposte che copre la rappresentazione esadecimale:

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;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.