Jak przekonwertować char w int?


123

Jaki jest właściwy sposób konwersji a charna int? To daje 49:

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

Nie chcę konwertować na ciąg, a następnie go analizować.


1
Możliwe powtórzenie tego pytania.
RBT

Możliwy duplikat Convert char to int w C #
GSerg

Odpowiedzi:


282

Dziwię się, że nikt nie wspomniał o metodzie statycznej wbudowanej w System.Char...

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

18
Dobre miejsce! +1 Bardzo dziwne, że zwraca doublejednak
Marc Gravell

4
Zgadzam się, nie mogę zrozumieć, dlaczego zwraca „double” - w jaki sposób pojedynczy znak może reprezentować liczbę zmiennoprzecinkową?
Joel Mueller

49
Istnieje wiele znaków Unicode, które reprezentują liczbę inną niż całkowita, np. U + 2153 .
dtb,

26
@dtb - nie brałem tego pod uwagę. Char.GetNumericValue('⅓')rzeczywiście wraca 0.3333.... Dzięki za zwrócenie uwagi!
Joel Mueller

1
Uwaga: ta funkcja nie jest obecnie dostępna w NetMF.
GisMofx

40

jak o (o char c)

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

co oznacza odjęcie wartości char?

Czy pytanie o API (komentarze), może metoda rozszerzenia?

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

następnie użyj int x = c.ParseInt32();


1
Powinienem był wspomnieć, wiedziałem o tym, ale czy jest inny sposób? Chciałem wiedzieć, czy istnieje API, które to robi?
tvr

4
Jeśli chcesz zachować zachowanie podobne do int.Parse, tj. Wyjątek jest zgłaszany przy nieprawidłowym wejściu, musisz dodać dodatkowe granice sprawdzające:if (i < 0 || i > 9) throw new FormatException();
Dirk Vollmar

@ user386338 Obawiam się, że nie ma.
Eugene Cheverda,

@ user386338 - zaktualizowano o opcję ponownego API, w tym również informację zwrotną @ 0xA3
Marc Gravell

@ user386338 - zobacz odpowiedź Joela na temat wbudowanej metody API
Marc Gravell

21

To, o czym wszyscy zapominają, to wyjaśnienie DLACZEGO tak się dzieje.

Char jest w zasadzie liczbą całkowitą, ale ze wskaźnikiem w tabeli ASCII. Wszystkie znaki mają odpowiadającą im wartość całkowitą, co wyraźnie widać, próbując ją przeanalizować.

Pranay ma wyraźnie inny zestaw znaków, dlatego jego kod nie działa. jedyny sposób to

int val = '1' - '0';

ponieważ wyszukuje wartość całkowitą w tabeli, '0'która jest wtedy „wartością podstawową”, odejmując od niej liczbę w formacie znakowym, otrzymamy oryginalną liczbę.


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

Jeszcze inna opcja:

int i = c & 0x0f;

Powinno to również umożliwić.


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

Można to zrobić za pomocą kodów ascii, gdzie „0” jest najniższą i od tego miejsca liczą się znaki liczbowe


To jest genialne! imo to najbardziej eleganckie rozwiązanie.
arabisoft

3
int val = '1' - 48;

@Luke Xu: „0” ma kod ASCII 0x30, czyli 48 dziesiętnie, więc jest to to samo, co „1” - „0”
NiKiZe

3

Możesz użyć następującej metody rozszerzenia:

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 Ogólnie sprawdzanie zakresu musi znajdować się na początku metody. Semantycznie, jeśli mamy dokonać konwersji charna, intmusimy sprawdzić zakres parametru wejściowego, a nie intwartość wyjściową .
Eugene Cheverda,

Nie ma potrzeby sprawdzania intwartości wyniku, ponieważ zakres znaków numerycznych został wykonany na początku metody, więc wynikowa wartość będzie poprawna, jeśli podany znak nie znajduje się w zakresie znaków numerycznych, zostanie wyrzucony wyjątek. Ta sama logika, którą podałeś, ale sprawdzanie zakresu jest wykonywane na początku metody.
Eugene Cheverda,

Przepraszamy, źle odczytałem próbkę kodu. Czasami trudno dostrzec najbardziej oczywiste rzeczy. Założę się, że kod mówił if (c < 0 || c > 9)...
Dirk Vollmar

1

Najbezpieczniejszym sposobem osiągnięcia tego jest użycie metody Int32.TryParse. Zobacz tutaj: http://dotnetperls.com/int-tryparse


TryParse jest dla ciągów znaków, a nie dla znaków
tvr

Tak, ale nadal jest to najbezpieczniejszy sposób na dokonanie konwersji
MUG4N

1
Konwersja pojedynczego znaku na liczbę całkowitą jest kwestią bezpieczeństwa?
Joel Mueller

1
„Bezpieczny” w tym przypadku oznacza, że ​​nie spowoduje to problemów, jeśli Twój znak nie jest w rzeczywistości liczbą ascii - może to być wielobajtowy znak Unicode.
Robin Bennett

1
int val = '1' & 15;

Binarny z znaków ASCII 0-9 to:

0 - 00110000

1 - 00110001

2 - 00110010

3 - 00110011

4 - 00110100

5 - 00110101

6 - 00110110

7 - 00110111

8 - 00111000

9 - 00111001

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


Jak to działa pod względem typów? używasz operatora bitowego między char i int, a następnie zwraca int? Czy logiczne AND używa binarnej reprezentacji zarówno znaku char, jak i int i zwraca reprezentację binarną, a następnie, gdy definiujesz zmienną jako int, używa tej reprezentacji?
mitomed

@mitnomed tak, a jeśli używasz na przykład bajtu, używa reprezentacji bajtu.
Tomer Wolberg

0

Możesz spróbować czegoś takiego:

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

dlaczego nie tylko .ToString ()?
Veikedo,

@Veikedo on chce int, a nie string.
briba

6
Mam na myśliConvert.ToInt32('1'.ToString())
Veikedo

0

Rozszerzenie niektórych innych odpowiedzi, które obejmuje reprezentację szesnastkową:

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