Konvertieren Sie char in int in C #

148

Ich habe ein Zeichen in c #:

char foo = '2';

Jetzt möchte ich die 2 in ein int bringen. Ich finde, dass Convert.ToInt32 den tatsächlichen Dezimalwert des Zeichens und nicht die Zahl 2 zurückgibt. Folgendes wird funktionieren:

int bar = Convert.ToInt32(new string(foo, 1));

int.parse funktioniert auch nur mit Strings.

Gibt es in C # keine native Funktion, um von einem Zeichen zu einem Int zu wechseln, ohne daraus einen String zu machen? Ich weiß, dass dies trivial ist, aber es scheint nur seltsam, dass es nichts Natives gibt, um die Konvertierung direkt durchzuführen.

KeithA
quelle

Antworten:

143

Interessante Antworten, aber die Dokumente sagen anders:

Verwenden Sie die GetNumericValueMethoden, um ein CharObjekt, das eine Zahl darstellt, in einen numerischen Werttyp zu konvertieren . Verwenden Sie Parseund TryParse, um ein Zeichen in einer Zeichenfolge in ein Char Objekt zu konvertieren . Verwenden Sie ToStringdiese Option , um ein Char Objekt in ein StringObjekt zu konvertieren .

http://msdn.microsoft.com/en-us/library/system.char.aspx

Chad Grant
quelle
ahh! Es gibt also etwas Eingeborenes! Seltsam, dass es ein Double zurückgibt. Diese Antwort gefällt mir besser. Vielen Dank für den Hinweis.
KeithA
92
@KeithA: Es gibt einen Grund dafür, das Doppelte zurückzugeben: char.GetNumericValue('¼')ergibt 0,25. Die Freuden von Unicode ... ;-)
Heinzi
1
Dies ist keine Antwort, die die eigentliche Frage beantwortet: Char.GetNumericValue ('o'), Char.GetNumericValue ('w') und nicht numerische Zeichen geben immer -1 zurück - Jeremy Ruten hat die richtige Antwort gepostet
Rusty Nail
2
@RustyNail im Fall der ursprünglichen Frage - speziell fragen, wo er weiß, dass das Zeichen eine Zahl darstellt - das ist die richtige Antwort
Don Cheadle
@mmcrae Ich glaube nicht - die ursprüngliche Frage verlangt char, intohne stringvorher zu verwenden.
NetMage
163

Dadurch wird es in ein int konvertiert:

char foo = '2';
int bar = foo - '0';

Dies funktioniert, weil jedes Zeichen intern durch eine Zahl dargestellt wird. Die Zeichen '0' bis '9' werden durch fortlaufende Zahlen dargestellt. Wenn Sie also den Unterschied zwischen den Zeichen '0' und '2' ermitteln, erhalten Sie die Zahl 2.

Jeremy Ruten
quelle
5
Es wird ein bestimmter Zeichensatz angenommen.
EricSchaefer
8
Nein, solange die Ziffern in Ordnung sind (welche Compiler den Zeichensatz benötigen), funktioniert es, egal mit welchem ​​Wert sie beginnen.
Jeremy Ruten
2
Dies ist in Ordnung, außer dass Sie zuerst noch die Grenzwerte überprüfen müssen, und an diesem Punkt bin ich mir nicht sicher, ob int.parse (foo.ToString ()) schneller ist.
Matthew Flaschen
7
@EricSchaefer Aber das ist eine sichere Annahme in C #: charist immer UTF-16.
Svick
2
@svick kleiner Punkt und alt jetzt, aber in der Zeit, seit Sie dies gepostet haben, haben wir Core herausgebracht, der UTF-8 verwendet. Trotzdem eine sichere Annahme.
Joel Coehoorn
84

Hat jemand darüber nachgedacht, dies zu verwenden int.Parse()und zu int.TryParse()mögen?

int bar = int.Parse(foo.ToString());

Noch besser so

int bar;
if (!int.TryParse(foo.ToString(), out bar))
{
    //Do something to correct the problem
}

Es ist viel sicherer und weniger fehleranfällig

fehlerhaft
quelle
2
Absolut der richtige Ansatz. Wählen Sie die erste, wenn Sie Nicht-Int-Eingaben auslösen möchten, die zweite, wenn Sie etwas anderes tun möchten.
Jay Bazuzi
Dies ist ein guter Ansatz für eine generische Konvertierungsmethode. Abgesehen davon ist es ein weiteres Beispiel dafür, wie .NET Bloatware fördert. (Ich meine, mach weiter und teste TryParse () und ToString () - das kannst du nicht, praktisch nicht).
Abmelden
5
@logout nein, es ist ein Beispiel dafür, wie eine Antwort auf StackOverflow Bloatware fördert. Dies ist in der Tat unnötig aufgebläht, und ich verstehe nicht, warum dies als überlegen gegenüber dem Subtrahieren '0'vom Zeichen angesehen wird.
Roman Starkov
26
char c = '1';
int i = (int)(c-'0');

und Sie können daraus eine statische Methode erstellen:

static int ToInt(this char c)
{
    return (int)(c - '0');
}
sontek
quelle
Das habe ich gesucht. Sie könnten vielleicht erklären, was Sie mit dem Minus-Null-Teil machen.
Xonatron
10

Versuche dies

char x = '9'; // '9' = ASCII 57

int b = x - '0'; //That is '9' - '0' = 57 - 48 = 9
RollerCosta
quelle
Ihr Kommentar sagt '9', aber Ihr Code hat 9, der nicht kompiliert werden kann.
Svick
7

Standardmäßig verwenden Sie UNICODE, daher empfehle ich die Verwendung der fehlerhaften Methode

int bar = int.Parse(foo.ToString());

Obwohl die numerischen Werte unter für Ziffern und grundlegende lateinische Zeichen gleich sind.

Nikolay
quelle
4

Dies wird in eine Ganzzahl konvertiert und behandelt Unicode

CharUnicodeInfo.GetDecimalDigitValue('2')

Sie können mehr lesen hier .

Dan Friedman
quelle
3

Der wahre Weg ist:

int theNameOfYourInt = (int) .Char.GetNumericValue (theNameOfYourChar);

"theNameOfYourInt" - das int, in das Ihr Zeichen umgewandelt werden soll.

"theNameOfYourChar" - Das Zeichen, das Sie verwenden möchten, damit es in ein int umgewandelt wird.

Lass alles andere sein.

Normantas Stankevičius
quelle
2

Prinzip:

char foo = '2';
int bar = foo & 15;

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

0   -   0011 0000
1   -   0011 0001
2   -   0011 0010
3   -   0011 0011
4   -   0011 0100
5   -   0011 0101
6   -   0011 0110
7   -   0011 0111
8   -   0011 1000
9   -   0011 1001

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, ...)

Verwendung:

public static int CharToInt(char c)
{
    return 0b0000_1111 & (byte) c;
}
Tomer Wolberg
quelle
2
Während dieses Code-Snippet die Lösung sein kann, hilft das Hinzufügen einer Erklärung wirklich, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage in Zukunft für Leser beantworten und diese Personen möglicherweise die Gründe für Ihren Codevorschlag nicht kennen.
Yivi
2

Ich bin mit @Chad Grant einverstanden

Auch richtig, wenn Sie in einen String konvertieren, können Sie diesen Wert als numerisch verwenden, wie in der Frage angegeben

int bar = Convert.ToInt32(new string(foo, 1)); // => gives bar=2

Ich habe versucht, ein einfacheres und verständlicheres Beispiel zu erstellen

char v = '1';
int vv = (int)char.GetNumericValue(v); 

char.GetNumericValue (v) gibt als double zurück und konvertiert in (int)

Mehr Erweiterte Verwendung als Array

int[] values = "41234".ToArray().Select(c=> (int)char.GetNumericValue(c)).ToArray();
Hamit YILDIRIM
quelle
0

Vergleich einiger Methoden basierend auf dem Ergebnis, wenn das Zeichen keine ASCII-Ziffer ist:

char c = '\n';                              
Debug.Print($"{c & 15}");                   // 10
Debug.Print($"{c ^ 48}");                   // 58
Debug.Print($"{c - 48}");                   // -38
Debug.Print($"{(uint)c - 48}");             // 4294967258
Debug.Print($"{char.GetNumericValue(c)}");  // -1 
Slai
quelle
0

Ich verwende Compact Framework 3.5 und habe keine "char.Parse" -Methode. Ich denke, es ist nicht schlecht, die Convert-Klasse zu verwenden. (Siehe CLR über C #, Jeffrey Richter)

char letterA = Convert.ToChar(65);
Console.WriteLine(letterA);
letterA = 'あ';
ushort valueA = Convert.ToUInt16(letterA);
Console.WriteLine(valueA);
char japaneseA = Convert.ToChar(valueA);
Console.WriteLine(japaneseA);

Funktioniert mit ASCII-Zeichen oder Unicode-Zeichen

Antonio
quelle
-4

Das hat bei mir funktioniert:

int bar = int.Parse("" + foo);
Renán Díaz
quelle
5
Wie unterscheidet sich das davon int.Parse(foo.ToString()), außer dass es weniger lesbar ist?
Svick
-5

Ich habe viele Antworten gesehen, aber sie scheinen mir verwirrend. Können wir nicht einfach Type Casting verwenden?

Zum Beispiel: -

int s;
char i= '2';
s = (int) i;
Lerner
quelle
1
Dies würde den ASCII-Code des Zeichens 2 zurückgeben, nicht den Wert 2.
cavpollo
Wie wäre es dann mit char.GetNumericValue (es gibt einen doppelten Wert zurück) und dem Casting in int.
Lerner
Ja, das ist, was @Chad Grants akzeptierte Antwort vorschlägt
cavpollo