Как преобразовать char в int?


124

Как правильно преобразовать a charв int? Это дает 49:

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

Я не хочу преобразовывать в строку, а затем разбирать ее.


1
Возможный дубликат этого вопроса.
— RBT

Возможный дубликат Convert char to int в C #
— GSerg

Ответы:


283

Я удивлен, что никто не упомянул статический метод, встроенный прямо в System.Char...

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

18
Хорошее место! +1 Очень странно , что она возвращает double, хотя
— Марк Gravell

4
Я согласен, я не могу понять, почему он возвращает double - как может один символ представлять число с плавающей запятой?
— Джоэл Мюллер

49
Есть много символов Unicode, которые представляют собой нецелые числа, например, U + 2153 .
— dtb

26
@dtb - я не думал об этом. Char.GetNumericValue('⅓')действительно возвращается 0.3333.... Спасибо что подметил это!
— Джоэл Мюллер,

1
Foot Note: эта функция в настоящее время недоступна в NetMF.
— GisMofx

40

как насчет (для char c)

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

что делает вычитание значения char?

Повторите вопрос API (комментарии), возможно, метод расширения?

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

затем используйте int x = c.ParseInt32();


1
Я должен был упомянуть, я знал об этом, но есть ли другой способ? Я хотел узнать, есть ли для этого API?
— tvr

4
Если вы хотите, чтобы поведение было похоже на int.Parseто, что исключение выбрасывается при недопустимом вводе, вам нужно будет добавить дополнительную проверку границ:if (i < 0 || i > 9) throw new FormatException();
— Дирк Воллмар,

@ user386338 Боюсь, что нет.
— Eugene Cheverda 08

@ user386338 - обновляется с опцией повторного API, также включая @ обратной связи 0xA3 в
— Marc Gravell

@ user386338 - см. ответ Джоэла о встроенном методе API
— Marc Gravell

21

Все забывают объяснить, ПОЧЕМУ это происходит.

Char - это целое число, но с указателем в таблице ASCII. Все символы имеют соответствующее целочисленное значение, как вы можете ясно видеть при его анализе.

У праная явно другой набор символов, поэтому ЕГО код не работает. единственный способ это

int val = '1' - '0';

потому что это ищет целочисленное значение в таблице, '0'которое затем является «базовым значением», вычитая из него ваше число в формате char, вы получите исходное число.


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

Еще один вариант:

int i = c & 0x0f;

Этого тоже должно достичь.


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

Это можно сделать с помощью кодов ascii, где '0' - наименьшее значение, а количество символов отсчитывается оттуда.


Это великолепно! Имо самое элегантное решение здесь.
— arabisoft

3
int val = '1' - 48;

@Luke Xu: '0' имеет код ASCII 0x30, который равен 48 в десятичной системе, так что это то же самое, что '1' - '0'
— NiKiZe

3

Вы можете использовать следующий метод расширения:

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 Обычно проверка диапазона должна быть в начале метода. Семантически, если мы хотим преобразовать charв, intмы должны проверять диапазон входного параметра, а не выходного intзначения.
— Евгений Чеверда 08

Нет необходимости проверять intзначение результата, потому что диапазон числовых символов был выполнен в начале метода, поэтому будет правильное результирующее значение, если указанный символ не находится в диапазоне числовых символов, будет выброшено исключение. Та же логика, что и вы, но проверка диапазона выполняется в начале метода.
— Eugene Cheverda 08

Извините, я неправильно прочитал ваш образец кода. Иногда трудно увидеть самые очевидные вещи. Готов поспорить, что в коде сказано if (c < 0 || c > 9)...
— Дирк Воллмар

1

Самый безопасный способ добиться этого - использовать метод Int32.TryParse. Смотрите здесь: http://dotnetperls.com/int-tryparse


TryParse предназначен для строк, а не для символов
— tvr

Да, но это все еще самый безопасный способ выполнить преобразование
— MUG4N

1
Преобразование одного символа в целое число - это вопрос безопасности?
— Джоэл Мюллер

1
«Безопасный» в этом случае означает, что это не вызовет проблем, если ваш char на самом деле не является числом ascii - это может быть многобайтовый символ Юникода.
— Робин Беннетт

1
int val = '1' & 15;

Двоичный код символов ASCII 0-9:

0 - 00110000

1 - 00110001

2 - 00110010

3 - 00110011

4 - 00110100

5 - 00110101

6 - 00110110

7 - 00110111

8 - 00111000

9 - 00111001

и если вы возьмете в каждый из них первые 4 LSB (используя побитовое И с 8'b00001111, что равно 15), вы получите фактическое число (0000 = 0,0001 = 1,0010 = 2, ...)


Как это работает с точки зрения типов? вы используете побитовый оператор между char и int, а затем возвращает int? Использует ли логическое И двоичное представление как char, так и int и возвращает ли двоичное представление, а затем, когда вы определяете var как int, он использует это представление?
— mitomed

@mitnomed да, и если вы используете, например, байт, тогда он использует байтовое представление.
— Tomer Wolberg

0

Вы можете попробовать что-то вроде этого:

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

почему не просто .ToString ()?
— Veikedo

@Veikedo он хочет int, а не строку.
— взятка

6
Я имею в видуConvert.ToInt32('1'.ToString())
— Вейкедо

0

Расширение некоторых других ответов, охватывающих шестнадцатеричное представление:

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;
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.