Wie konvertiere ich char in int?

123

Was ist der richtige Weg, um ein charzu konvertieren int? Dies gibt 49:

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

Ich möchte nicht in einen String konvertieren und ihn dann analysieren.

tvr
quelle
1
Mögliches Duplikat dieser Frage.
RBT
Mögliches Duplikat von
Zeichen

Antworten:

282

Ich bin überrascht, dass niemand die statische Methode erwähnt hat, die direkt in System.Char...

int val = (int)Char.GetNumericValue('8');
// val == 8
Joel Mueller
quelle
18
Gute Stelle! +1 Sehr seltsam, dass es ein doublegibt
Marc Gravell
4
Ich stimme zu, ich kann nicht herausfinden, warum es 'double' zurückgibt - wie kann ein einzelnes Zeichen möglicherweise eine Gleitkommazahl darstellen?
Joel Mueller
49
Es gibt viele Unicode-Zeichen, die eine nicht ganzzahlige Zahl darstellen, z. B. U + 2153 .
dtb
26
@dtb - das hatte ich nicht bedacht. Char.GetNumericValue('⅓')kommt in der Tat zurück 0.3333.... Vielen Dank für den Hinweis!
Joel Mueller
1
Fuß Hinweis: Diese Funktion ist derzeit in NetMF nicht verfügbar.
GisMofx
40

wie wäre es mit (für char c)

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

Was bedeutet Subtraktion des Zeichenwerts?

Bezüglich der API-Frage (Kommentare), vielleicht eine Erweiterungsmethode?

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

dann benutze int x = c.ParseInt32();

Marc Gravell
quelle
1
Ich hätte erwähnen sollen, ich wusste davon, aber gibt es einen anderen Weg? Ich wollte wissen, ob es eine API dafür gibt.
TVR
4
Wenn Sie ein ähnliches Verhalten wünschen int.Parse, dh dass bei ungültigen Eingaben eine Ausnahme ausgelöst wird, müssen Sie zusätzliche Grenzüberprüfungen hinzufügen:if (i < 0 || i > 9) throw new FormatException();
Dirk Vollmar
@ user386338 Ich fürchte, das gibt es nicht.
Eugene Cheverda
@ user386338 - aktualisiert mit einer Option bezüglich der API, einschließlich des Feedbacks von @ 0xA3
Marc Gravell
@ user386338 - siehe Joels Antwort für eine eingebaute API-Methode
Marc Gravell
21

Was jeder vergisst, ist zu erklären, WARUM dies geschieht.

Ein Zeichen ist im Grunde eine Ganzzahl, jedoch mit einem Zeiger in der ASCII-Tabelle. Alle Zeichen haben einen entsprechenden ganzzahligen Wert, wie Sie deutlich sehen können, wenn Sie versuchen, ihn zu analysieren.

Pranay hat eindeutig einen anderen Zeichensatz, deshalb funktioniert sein Code nicht. Der einzige Weg ist

int val = '1' - '0';

Da dies den ganzzahligen Wert in der Tabelle nachschlägt, dessen Basiswert '0'dann Ihre Zahl im Zeichenformat subtrahiert, erhalten Sie die ursprüngliche Zahl.

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

Noch eine Option:

int i = c & 0x0f;

Dies sollte auch dies erreichen.

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

Dies kann mit ASCII-Codes erfolgen, wobei '0' die niedrigste ist und die Anzahl der Zeichen von dort hoch zählt

Tristan
quelle
Das ist brilliant! Imo die eleganteste Lösung hier.
Arabisoft
3
int val = '1' - 48;
x2.
quelle
@ Luke Xu: '0' hat den ASCII-Code 0x30, der 48 dezimal ist, also ist dies dasselbe wie '1' - '0'
NiKiZe
3

Sie können die folgende Erweiterungsmethode verwenden:

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';
        }
    }
Eugene Cheverda
quelle
1
@ 0xA3 Die Bereichsprüfung muss im Allgemeinen am Anfang der Methode stehen. Semantisch , wenn wir zu konvertieren sind , charum intuns Bereich des Eingangsparameters zu überprüfen, nicht der intAusgangswert.
Eugene Cheverda
Der Ergebniswert intmuss nicht überprüft werden, da der Bereich der numerischen Zeichen zu Beginn der Methode ausgeführt wurde. Daher wird der korrekte Ergebniswert angezeigt. Wenn das angegebene Zeichen nicht im Bereich der numerischen Zeichen liegt, wird eine Ausnahme ausgelöst. Die gleiche Logik wie von Ihnen angegeben, jedoch die Bereichsprüfung wird zu Beginn der Methode durchgeführt.
Eugene Cheverda
Entschuldigung, ich habe Ihr Codebeispiel falsch gelesen. Manchmal ist es schwierig, die offensichtlichsten Dinge zu erkennen. Ich würde wetten, dass der Code sagte if (c < 0 || c > 9)...
Dirk Vollmar
1

Der sicherste Weg, dies zu erreichen, ist die Verwendung der Int32.TryParse-Methode. Siehe hier: http://dotnetperls.com/int-tryparse

MUG4N
quelle
TryParse ist für Zeichenfolgen, nicht für Zeichen
tvr
Ja, es ist aber immer noch der sicherste Weg, um die Konvertierung
durchzuführen
1
Das Konvertieren eines einzelnen Zeichens in eine Ganzzahl ist eine Sicherheitsfrage?
Joel Mueller
1
'Sicher' bedeutet in diesem Fall, dass es keine Probleme verursacht, wenn Ihr Zeichen keine ASCII-Nummer ist - es kann sich um ein Multi-Byte-Unicode-Zeichen handeln.
Robin Bennett
1
int val = '1' & 15;

Die Binärdatei der ASCII-Zeichen 0-9 lautet:

0 - 00110000

1 - 00110001

2 - 00110010

3 - 00110011

4 - 00110100

5 - 00110101

6 - 00110110

7 - 00110111

8 - 00111000

9 - 00111001

und wenn Sie in jedem von ihnen die ersten 4 LSB (mit bitweisem UND mit 8'b00001111, was 15 entspricht) aufnehmen, erhalten Sie die tatsächliche Zahl (0000 = 0,0001 = 1,0010 = 2, ...)

Tomer Wolberg
quelle
Wie funktioniert das in Bezug auf Typen? Sie verwenden einen bitweisen Operator zwischen einem Zeichen und einem Int und geben dann ein Int zurück? Verwendet das logische UND die binäre Darstellung sowohl des Zeichens als auch des int und gibt eine binäre Darstellung zurück. Wenn Sie dann die var als int definieren, verwendet es diese Darstellung?
Mitomed
@mitnomed yes und wenn Sie beispielsweise Byte verwenden, wird die Bytedarstellung verwendet.
Tomer Wolberg
0

Sie können so etwas ausprobieren:

int val = Convert.ToInt32("" + '1');
Bestechung
quelle
warum nicht einfach .ToString ()?
Veikedo
@Veikedo er will ein int und keine Zeichenfolge.
Briba
6
Ich meineConvert.ToInt32('1'.ToString())
Veikedo
0

Eine Erweiterung einiger anderer Antworten, die die hexadezimale Darstellung abdeckt:

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
quelle