Converter char para int em C #

148

Eu tenho um caractere em c #:

char foo = '2';

Agora eu quero colocar o 2 em um int. Acho que Convert.ToInt32 retorna o valor decimal real do caractere e não o número 2. O seguinte funcionará:

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

O int.parse também funciona apenas em strings.

Não existe nenhuma função nativa no C # para passar de um char para int sem torná-lo uma string? Eu sei que isso é trivial, mas parece estranho que não haja nada nativo para fazer diretamente a conversão.

KeithA
fonte

Respostas:

143

Respostas interessantes, mas os documentos dizem de forma diferente:

Use os GetNumericValuemétodos para converter um Charobjeto que representa um número em um tipo de valor numérico. Use Parsee TryParsepara converter um caractere em uma string em um Char objeto. Use ToStringpara converter um Char objeto em um Stringobjeto.

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

Chad Grant
fonte
ahh! então há algo nativo! Estranho que retorne um dobro. Eu gosto mais desta resposta. Obrigado por apontar isso.
Keitha
92
@ KeithA: Há uma razão para retornar em dobro: char.GetNumericValue('¼')produz 0,25. As alegrias de Unicode ... ;-)
Heinzi
1
Esta não é uma resposta que responda à pergunta real, Char.GetNumericValue ('o'), Char.GetNumericValue ('w') e qualquer caractere não numérico sempre retornará -1 - Jeremy Ruten postou a resposta correta
Rusty Nail
2
@RustyNail no caso da pergunta original - pedindo especificamente onde ele sabe o caractere representa um número - esta é a resposta certa
Don Cheadle
@mmcrae Eu não penso assim - a pergunta original pede charpara intsem usar stringpela primeira vez.
NetMage 25/03/19
163

Isso o converterá em um int:

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

Isso funciona porque cada caractere é representado internamente por um número. Os caracteres '0' a '9' são representados por números consecutivos, portanto, encontrar a diferença entre os caracteres '0' e '2' resulta no número 2.

Jeremy Ruten
fonte
5
Ele assume um determinado conjunto de caracteres.
EricSchaefer 27/10/08
8
Não, não, desde que os dígitos estejam em ordem (que compiladores exigem do conjunto de caracteres) funcionará, independentemente do valor em que eles começarem.
Jeremy Ruten 27/10/08
2
Isso é bom, exceto que você ainda precisa fazer a verificação de limites primeiro e, nesse ponto, não tenho certeza se int.parse (foo.ToString ()) é mais rápido.
22415 Matthew Flaschen
7
@ EricSchaefer Mas essa é uma suposição segura em C #: charé sempre UTF-16.
Svick
2
@ svick pequeno e antigo agora, mas desde que você postou isso, tivemos o Core, que usa UTF-8. Ainda é uma suposição segura, no entanto.
Joel Coehoorn
84

Alguém já pensou em usar int.Parse()e int.TryParse()assim

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

Ainda melhor assim

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

É muito mais seguro e menos propenso a erros

defeituoso
fonte
2
Absolutamente a abordagem correta. Escolha a primeira se desejar que entradas não int sejam lançadas, a segunda se desejar fazer outra coisa.
Jay Bazuzi 27/10/08
Essa é uma boa abordagem para um método de conversão genérico. Como um aparte, é outro exemplo de como o .NET promove bloatware. (Quero dizer, faça o teste de unidade TryParse () e ToString () - você não pode, não praticamente).
logout
5
@ logout não, é um exemplo de como uma resposta no StackOverflow promove bloatware. Isso é realmente desnecessariamente inchado, e não entendo por que isso é considerado superior à subtração '0'do caractere.
Roman Starkov
26
char c = '1';
int i = (int)(c-'0');

e você pode criar um método estático a partir dele:

static int ToInt(this char c)
{
    return (int)(c - '0');
}
sontek
fonte
Era isso que eu estava procurando. Talvez você possa explicar o que está fazendo com a parte menos zero.
Xonatron
10

Tente isto

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

int b = x - '0'; //That is '9' - '0' = 57 - 48 = 9
RollerCosta
fonte
Seu comentário diz '9', mas seu código possui 9, o que não será compilado.
Svick
7

Por padrão, você usa UNICODE, então sugiro usar o método defeituoso

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

Mesmo que os valores numéricos abaixo sejam os mesmos para dígitos e caracteres latinos básicos.

Nikolay
fonte
4

Isso converte em um número inteiro e manipula unicode

CharUnicodeInfo.GetDecimalDigitValue('2')

Você pode ler mais aqui .

Dan Friedman
fonte
3

A maneira real é:

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

"theNameOfYourInt" - o int para o qual você deseja que seu char seja transformado.

"theNameOfYourChar" - O Char que você deseja que seja usado para que seja transformado em um int.

Deixe tudo o resto.

Normantas Stankevičius
fonte
2

Princípio:

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

O binário dos caracteres 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

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

Uso:

public static int CharToInt(char c)
{
    return 0b0000_1111 & (byte) c;
}
Tomer Wolberg
fonte
2
Embora esse snippet de código possa ser a solução, incluir uma explicação realmente ajuda a melhorar a qualidade da sua postagem. Lembre-se de que você está respondendo à pergunta dos leitores no futuro e essas pessoas podem não saber os motivos da sua sugestão de código.
yivi
2

Estou de acordo com @Chad Grant

Também à direita, se você converter para string, poderá usar esse valor como numérico, conforme mencionado na pergunta

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

Eu tentei criar um exemplo mais simples e compreensível

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

char.GetNumericValue (v) retorna como duplo e converte para (int)

Uso mais avançado como uma matriz

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

Comparação de alguns dos métodos com base no resultado quando o caractere não é um dígito 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 
Slai
fonte
0

Estou usando o Compact Framework 3.5 e não possui um método "char.Parse". Eu acho que não é ruim usar a classe Convert. (Veja CLR via 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);

Funciona com caracteres ASCII ou Unicode

antonio
fonte
-4

Isso funcionou para mim:

int bar = int.Parse("" + foo);
Renán Díaz
fonte
5
Como isso é diferente int.Parse(foo.ToString()), exceto por ser menos legível?
svick
-5

Eu já vi muitas respostas, mas elas me parecem confusas. Não podemos simplesmente usar a conversão de tipo.

Por exemplo: -

int s;
char i= '2';
s = (int) i;
Aprendiz
fonte
1
Isso retorna o código ASCII do caráter 2, não o valor 2.
cavpollo
Então, que tal usar char.GetNumericValue (retorna um valor duplo) e convertê-lo para int.
Learner
Sim, isso é o que resposta aceita de @Chad Grant propõe
cavpollo