Konwertuj char na int w C #


148

Mam znak w C #:

char foo = '2';

Teraz chcę wstawić 2 do int. Uważam, że Convert.ToInt32 zwraca rzeczywistą wartość dziesiętną znaku, a nie liczbę 2. Działa to:

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

int.parse działa również tylko na stringach.

Czy nie ma natywnej funkcji w C #, aby przejść od znaku do int bez tworzenia ciągu? Wiem, że to trywialne, ale wydaje się dziwne, że nie ma nic rodzimego, który mógłby bezpośrednio dokonać konwersji.

Odpowiedzi:


143

Ciekawe odpowiedzi, ale doktorzy mówią inaczej:

Użyj GetNumericValuemetod, aby przekonwertować Charobiekt, który reprezentuje liczbę na typ wartości liczbowej. Użyj Parsei, TryParseaby przekonwertować znak w ciągu na Char obiekt. Służy ToStringdo konwersji Char obiektu na Stringobiekt.

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


ach! więc jest coś rodzimego! Dziwne, że zwraca podwójną. Ta odpowiedź podoba mi się bardziej. Dzięki za wskazanie tego.
KeithA

92
@KeithA: Jest powód, dla którego zwraca wartość double: char.GetNumericValue('¼')daje 0,25. Radości z Unicode ... ;-)
Heinzi

1
To nie jest odpowiedź, która odpowiada na rzeczywiste pytanie, Char.GetNumericValue ('o'), Char.GetNumericValue ('w'), a każdy nienumeryczny znak zawsze zwróci -1 - Jeremy Ruten opublikował poprawną odpowiedź
Rusty Nail

2
@RustyNail w przypadku oryginalnego pytania - pytając konkretnie, gdzie wie, że znak reprezentuje liczbę - to jest właściwa odpowiedź
Don Cheadle

@mmcrae Nie sądzę - pierwotne pytanie prosi o to, charaby intnie używać stringnajpierw.
NetMage,

163

Spowoduje to przekonwertowanie go na int:

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

To działa, ponieważ każdy znak jest wewnętrznie reprezentowany przez liczbę. Znaki od „0” do „9” są reprezentowane przez kolejne liczby, więc znalezienie różnicy między znakami „0” i „2” daje w wyniku liczbę 2.


5
Zakłada określony zestaw znaków.
EricSchaefer

8
Nie, nie, tak długo, jak cyfry są w porządku (których kompilatory wymagają zestawu znaków), będzie działać, bez względu na to, od jakiej wartości zaczną.
Jeremy Ruten

2
To jest w porządku, z wyjątkiem tego, że nadal musisz najpierw sprawdzić granice, a na tym etapie nie jestem pewien, czy int.parse (foo.ToString ()) jest szybsze.
Matthew Flaschen

7
@EricSchaefer Ale to bezpieczne założenie w C #: charto zawsze UTF-16.
svick

2
@svick mały punkt i teraz stary, ale od czasu, gdy to opublikowałeś, wyszedł Core, który używa UTF-8. Wciąż jednak bezpieczne założenie.
Joel Coehoorn

84

Czy ktoś rozważał użycie int.Parse()i int.TryParse()jak to

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

Jeszcze lepiej

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

Jest dużo bezpieczniejszy i mniej podatny na błędy


2
Absolutnie właściwe podejście. Wybierz pierwszą, jeśli chcesz, aby dane wejściowe inne niż int są rzucane, a drugą, jeśli chcesz zrobić coś innego.
Jay Bazuzi

To dobre podejście w przypadku ogólnej metody konwersji. Na marginesie, jest to kolejny przykład tego, jak .NET promuje oprogramowanie typu bloatware. (Mam na myśli kontynuowanie i test jednostkowy TryParse () i ToString () - nie możesz, praktycznie nie).
wyloguj się

5
@logout nie, to przykład tego, jak odpowiedź na StackOverflow promuje oprogramowanie typu bloatware. To jest rzeczywiście niepotrzebnie rozdęte i nie rozumiem, dlaczego uważa się to za lepsze od odejmowania '0'od znaku.
Roman Starkov

26
char c = '1';
int i = (int)(c-'0');

i możesz z tego stworzyć statyczną metodę:

static int ToInt(this char c)
{
    return (int)(c - '0');
}

To jest to, czego szukałem. Mógłbyś może wyjaśnić, co robisz z częścią minus zero.
Xonatron

10

Spróbuj tego

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

int b = x - '0'; //That is '9' - '0' = 57 - 48 = 9

Twój komentarz mówi '9', ale twój kod tak 9, co się nie kompiluje.
svick

7

Domyślnie używasz UNICODE, więc sugeruję użycie metody wadliwego

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

Mimo że wartości numeryczne pod są takie same dla cyfr i podstawowych znaków łacińskich.


4

To konwertuje na liczbę całkowitą i obsługuje Unicode

CharUnicodeInfo.GetDecimalDigitValue('2')

Możesz przeczytać więcej tutaj .


4

Prawdziwy sposób to:

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

„theNameOfYourInt” - int, w jaki chcesz przekształcić postać.

"theNameOfYourChar" - Char, którego chcesz użyć, aby został przekształcony w int.

Zostaw wszystko inne.


2

Zasada:

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

Binarny z znaków ASCII 0-9 to:

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

a jeśli weźmiesz do każdego z nich pierwsze 4 LSB (używając bitowego AND z 8'b00001111, co równa się 15), otrzymasz rzeczywistą liczbę (0000 = 0,0001 = 1,0010 = 2, ...)

Stosowanie:

public static int CharToInt(char c)
{
    return 0b0000_1111 & (byte) c;
}

2
Chociaż ten fragment kodu może być rozwiązaniem, dołączenie wyjaśnienia naprawdę pomaga poprawić jakość Twojego posta. Pamiętaj, że odpowiadasz na pytanie do czytelników w przyszłości, a osoby te mogą nie znać powodów, dla których zaproponowałeś kod.
yivi

2

Zgadzam się z @Chad Grant

Również dobrze, jeśli przekonwertujesz na łańcuch, możesz użyć tej wartości jako wartości liczbowej, jak powiedziano w pytaniu

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

Starałem się stworzyć prostszy i bardziej zrozumiały przykład

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

char.GetNumericValue (v) zwraca jako double i konwertuje na (int)

Bardziej zaawansowane zastosowanie jako tablica

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

0

Porównanie niektórych metod opartych na wyniku, gdy znak nie jest cyfrą ASCII:

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 

0

Używam Compact Framework 3.5 i nie mam metody „char.Parse”. Myślę, że nie jest źle używać klasy Convert. (Zobacz CLR przez 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);

Działa ze znakami ASCII lub Unicode


-4

To zadziałało dla mnie:

int bar = int.Parse("" + foo);

5
Czym się to różni od tego int.Parse(foo.ToString()), że jest mniej czytelne?
svick

-5

Widziałem wiele odpowiedzi, ale wydają mi się one zagmatwane. Nie możemy po prostu użyć rzutowania typów.

Na przykład: -

int s;
char i= '2';
s = (int) i;

1
To zwróci kod ASCII znaku 2, a nie wartość 2.
cavpollo

A co powiesz na użycie char.GetNumericValue (zwraca podwójną wartość) i rzutowanie jej na int.
Learner

Tak, to właśnie proponuje zaakceptowana odpowiedź @Chad Grant
Cavpollo
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.