Преобразование char в int в C#

У меня есть символ в C#:

char foo = '2';

Теперь я хочу получить 2 в int. Я обнаружил, что Convert.ToInt32 возвращает фактическое десятичное значение символа, а не число 2. Будет работать следующее:

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

int.parse также работает только со строками.

Нет ли в C# собственной функции для перехода от char к int, не превращая его в строку? Я знаю, что это тривиально, но кажется странным, что нет ничего родного, чтобы напрямую выполнить преобразование.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
171
0
405 342
14
Перейти к ответу Данный вопрос помечен как решенный

Ответы 14

Это преобразует его в int:

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

Это работает, потому что каждый символ внутренне представлен числом. Символы от «0» до «9» представлены последовательными числами, поэтому при обнаружении разницы между символами «0» и «2» будет получено число 2.

Предполагает определенный набор символов.

EricSchaefer 27.10.2008 11:32

Нет, это не так, пока цифры в порядке (какие компиляторы требуют от кодировки), он будет работать, независимо от того, с какого значения они начинаются.

Jeremy Ruten 27.10.2008 17:29

Это нормально, за исключением того, что вам все равно нужно сначала выполнить проверку границ, и в этот момент я не уверен, быстрее ли int.parse (foo.ToString ()).

Matthew Flaschen 26.04.2009 07:39

@EricSchaefer Но это безопасное предположение в C#: char всегда UTF-16.

svick 14.05.2014 19:48

Это работает и с буквами ... так что вы можете сделать: char foo = 'b'; int bar = foo - 'а'; // теперь вы можете видеть, что 'bar' - это вторая буква (индекс 1) в алфавите.

Sean Colombo 04.06.2015 03:19

@svick маленькая точка и сейчас старая, но за то время, когда вы опубликовали это, у нас вышло Core, которое использует UTF-8. Тем не менее, предположение остается безопасным.

Joel Coehoorn 12.12.2018 22:49

@JoelCoehoorn: Это неправда, char в .Net Core по-прежнему UTF-16. Ведется работа по добавлению строки UTF-8 в будущую версию .Net Core., но даже это не изменит char.

svick 13.12.2018 01:22

Просто вау ... впечатляет. И я работал с наборами символов весь день с тяжелыми преобразованиями в десятичные (т.е. числовые) значения int / uint, больше / меньше сравнений и т.д., но никогда не думал об этом простом, но блестящем способе.

Nicholas Petersen 02.03.2019 03:43

Для F# необходимо добавить явное приведение: int foo - int '0'

dudeNumber4 19.02.2020 19:04
char foo = 'a'; int bar = foo - '0'; -> bar == 49, что, вероятно, не то, что вам нужно. Вы захотите потом проверить этот 0 <= bar <= 9.
AaronHolland 09.06.2020 06:03

Предупреждение: это нестандартное решение. Он не работает с локализованными цифрами (например, арабскими цифрами). Вот почему это действительно работает только для ASCII.

Javid 18.02.2021 21:11
char c = '1';
int i = (int)(c-'0');

и вы можете создать из него статический метод:

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

Это то, что я искал. Возможно, вы могли бы объяснить, что вы делаете, с отрицательной частью нуля.

Xonatron 31.05.2018 04:18

Кто-нибудь думал об использовании int.Parse() и int.TryParse() как это

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

Даже лучше, как это

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

Это намного безопаснее и меньше подвержено ошибкам

Абсолютно правильный подход. Выберите первый, если вы хотите, чтобы вводились не-int, а второй, если вы хотите сделать что-то еще.

Jay Bazuzi 27.10.2008 08:41

Это хороший подход для универсального метода преобразования. В стороне, это еще один пример того, как .NET продвигает вредоносное ПО. (Я имею в виду продолжайте и проводите модульное тестирование TryParse () и ToString () - вы не можете, практически).

logout 19.08.2010 15:55

@logout нет, это пример того, как ответ на StackOverflow продвигает вредоносное ПО. Это действительно излишне раздутый, и я не понимаю, почему это считается лучше, чем вычитание '0' из символа.

Roman Starkov 22.09.2014 05:32
Ответ принят как подходящий

Интересные ответы, но документы говорят иначе:

Use the GetNumericValue methods to convert a Char object that represents a number to a numeric value type. Use Parse and TryParse to convert a character in a string into a Char object. Use ToString to convert a Char object to a String object.

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

Ах! так что есть что-то родное! Странно, что он возвращает двойной. Мне этот ответ больше нравится. Спасибо, что указали на это.

KeithA 28.04.2009 18:35

@KeithA: У него есть причина возвращать double: char.GetNumericValue('¼') дает 0,25. Радости Unicode ... ;-)

Heinzi 26.06.2012 14:09

Это не ответ, который отвечает на фактический вопрос, Char.GetNumericValue ('o'), Char.GetNumericValue ('w'), и любой нечисловой char всегда будет возвращать -1 - Джереми Рутен опубликовал правильный ответ

Rusty Nail 26.01.2017 11:20

@RustyNail в случае исходного вопроса - спрашивая конкретно, где он знает, что символ представляет собой число - это - правильный ответ

Don Cheadle 16.02.2018 22:45

@mmcrae Я так не думаю - исходный вопрос требует от char до int без предварительного использования string.

NetMage 25.03.2019 23:31
if (char.IsDigit(character) == true) { return char.GetNumericValue(character); }
JohnB 17.12.2019 23:26

Этот ответ был бы более полезным, если бы он показал примеры кода.

SendETHToThisAddress 30.09.2020 20:29

Попробуйте это

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

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

В вашем комментарии написано '9', но в вашем коде есть 9, который не компилируется.

svick 14.05.2014 19:50

По умолчанию вы используете UNICODE, поэтому я предлагаю использовать ошибочный метод

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

Несмотря на то, что числовые значения под цифрами и основными латинскими символами совпадают.

Это сработало для меня:

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

Чем это отличается от int.Parse(foo.ToString()), кроме того, что он менее читабелен?

svick 14.05.2014 19:51

Преобразуется в целое число и обрабатывает Unicode.

CharUnicodeInfo.GetDecimalDigitValue('2')

Вы можете прочитать больше здесь.

Я использую Compact Framework 3.5, и у меня нет метода char.Parse. Думаю, неплохо использовать класс Convert. (См. CLR через C#, Джеффри Рихтер)

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

Работает с символами ASCII или Unicode.

Сравнение некоторых методов на основе результата, когда символ не является цифрой ASCII:

char c1 = (char)('0' - 1), c2 = (char)('9' + 1); 

Debug.Print($"{c1 & 15}, {c2 & 15}");                                   // 15, 10
Debug.Print($"{c1 ^ '0'}, {c2 ^ '0'}");                                 // 31, 10
Debug.Print($"{c1 - '0'}, {c2 - '0'}");                                 // -1, 10
Debug.Print($"{(uint)c1 - '0'}, {(uint)c2 - '0'}");                     // 4294967295, 10
Debug.Print($"{char.GetNumericValue(c1)}, {char.GetNumericValue(c2)}"); // -1, -1

Я видел много ответов, но они меня сбивают с толку. Разве мы не можем просто использовать приведение типов.

Например: -

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

Это вернет код ASCII символа 2, а не значение 2.

cavpollo 29.05.2017 21:45

Тогда как насчет использования char.GetNumericValue (он возвращает двойное значение) и преобразования его в int.

Learner 06.09.2017 20:10

Да, это то, что предлагает принятый ответ @Chad Grant

cavpollo 07.09.2017 09:12

это было то, что я искал, когда нашел этот стек

Lilith Schneider 03.02.2021 00:21

Принцип:

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

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

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

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

Использование:

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

Хотя этот фрагмент кода может быть решением, включая объяснение действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причины вашего предложения кода.

yivi 26.12.2017 12:25

Настоящий способ:

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

"theNameOfYourInt" - int, в которое должен быть преобразован ваш char.

"theNameOfYourChar" - Char, который вы хотите использовать, чтобы он был преобразован в int.

Оставьте все остальное в покое.

Я согласен с @Chad Grant

Также правильно, если вы конвертируете в строку, вы можете использовать это значение как числовое, как указано в вопросе

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

Я постарался создать более простой и понятный пример

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

char.GetNumericValue (v) возвращается как double и преобразуется в (int)

Более расширенное использование в виде массива

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

Другие вопросы по теме