Como converter char para int?


123

Qual é a maneira correta de converter um charpara int? Isso fornece 49:

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

Não quero converter em string e analisá-lo.


1
Possível duplicata desta pergunta.
RBT

Possível duplicata do Convert char para int em C #
GSerg

Respostas:


282

Estou surpreso que ninguém tenha mencionado o método estático incorporado System.Char...

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

18
Bom local! +1 É muito estranho que retorne um double, no entanto
Marc Gravell

4
Concordo, não consigo descobrir por que ele retorna 'double' - como um único caractere pode representar um número de ponto flutuante?
Joel Mueller

49
Existem muitos caracteres Unicode que representam um número não inteiro, por exemplo, U + 2153 .
dtb 13/09/10

26
@ dtb - eu não tinha considerado isso. Char.GetNumericValue('⅓')realmente retorna 0.3333.... Obrigado por apontar isso!
Joel Mueller

1
Nota: atualmente, esta função não está disponível no NetMF.
GisMofx 10/08/2015

40

que tal (para char c)

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

qual a subtração do valor do char?

Re questão da API (comentários), talvez um método de extensão?

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

então use int x = c.ParseInt32();


1
Eu deveria ter mencionado, eu sabia disso, mas existe alguma outra maneira? Eu queria saber se existe uma API para fazer isso?
Tv

4
Se você quer um similiar bahavior para int.Parse, ou seja, que uma exceção é lançada na entrada inválida que você precisa adicionar limites adicionais verificando:if (i < 0 || i > 9) throw new FormatException();
Dirk Vollmar

@ user386338 Receio que não exista.
Eugene Cheverda

@ user386338 - atualizado com uma opção de API, incluindo também os comentários de @ 0xA3
Marc Gravell

@ user386338 - veja a resposta de Joel para um método API embutido
Marc Gravell

21

O que todo mundo está esquecendo está explicando POR QUE isso acontece.

Um caractere é basicamente um número inteiro, mas com um ponteiro na tabela ASCII. Todos os caracteres têm um valor inteiro correspondente, como você pode ver claramente ao tentar analisá-lo.

Pranay tem claramente um conjunto de caracteres diferente, é por isso que o código HIS não funciona. o único caminho é

int val = '1' - '0';

porque isso consulta o valor inteiro na tabela, '0'que é o 'valor base' subtraindo seu número no formato char, fornecendo o número original.


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

Mais uma opção:

int i = c & 0x0f;

Isso deve fazer isso também.


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

Isso pode ser feito usando códigos ASCII, onde '0' é o mais baixo e o número de caracteres é contado a partir daí.


Isto é brilhante! a solução mais elegante aqui.
arabisoft 23/03

3
int val = '1' - 48;

@Luke Xu: '0' tem o código ASCII 0x30 que é 48 em decimal por isso este é o mesmo que '1' - '0'
NiKiZe

3

Você pode usar o seguinte método de extensão:

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 A verificação do alcance deve ser realizada no início do método em geral. Semanticamente, se quisermos converter charpara int, temos que verificar a faixa do parâmetro de entrada, não o intvalor de saída .
Eugene Cheverda 08/09/10

Não há necessidade de verificar o intvalor do resultado, pois o intervalo de caracteres numéricos foi executado no início do método, portanto, haverá um valor resultante correto; se o caractere especificado não estiver no intervalo de caracteres numéricos, será gerada uma exceção. A mesma lógica que você forneceu, mas a verificação do intervalo é realizada no início do método.
Eugene Cheverda

Desculpe, eu estava interpretando mal seu exemplo de código. Às vezes é difícil ver as coisas mais óbvias. Aposto que o código dizia if (c < 0 || c > 9)...
Dirk Vollmar 08/09

1

A maneira mais segura de fazer isso é usando o método Int32.TryParse. Veja aqui: http://dotnetperls.com/int-tryparse


TryParse é para cordas não para caracteres
TVR

Sim, é, mas Stille a maneira mais segura de realizar a conversão
MUG4N

1
Converter um único caractere para um número inteiro é uma questão de segurança?
Joel Mueller

1
'Seguro' nesse caso significa que não causará problemas se o seu caractere não for realmente um número ascii - pode ser um caractere unicode de vários bytes.
Robin Bennett

1
int val = '1' & 15;

O binário dos caracteres ASCII 0-9 é:

0 - 00110000

1 - 00110001

2 - 00110010

3 - 00110011

4 - 00110100

5 - 00110101

6 - 00110110

7 - 00110111

8 - 00111000

9 - 00111001

e se você pegar em cada um deles os primeiros 4 LSB (usando AND bit a bit com 8'b00001111 igual a 15), obterá o número real (0000 = 0,0001 = 1,0010 = 2, ...)


Como isso funciona em termos de tipos? você está usando um operador bit a bit entre um char e um int e, em seguida, retorna um int? O AND lógico usa a representação binária do char e do int e retorna uma representação binária e, ao definir o var como int, ele usa essa representação?
Mitomed

@mitnomed yes e se você usa byte, por exemplo, ele usa a representação de bytes.
Tomer Wolberg

0

Você pode tentar algo como isto:

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

por que não apenas .ToString ()?
Veikedo 25/02

@Veikedo ele quer um int, e não uma string.
Briba 28/04

6
Quero dizerConvert.ToInt32('1'.ToString())
Veikedo

0

Uma extensão de algumas outras respostas que abrangem a representação hexadecimal:

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;
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.