Convertir char a int en C #

149

Tengo un char en c #:

char foo = '2';

Ahora quiero obtener el 2 en un int. Encuentro que Convert.ToInt32 devuelve el valor decimal real del carácter y no el número 2. Lo siguiente funcionará:

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

int.parse solo funciona en cadenas también.

¿No hay una función nativa en C # para pasar de un carácter a int sin convertirlo en una cadena? Sé que esto es trivial, pero parece extraño que no haya nada nativo para hacer la conversión directamente.

KeithA
fuente

Respuestas:

144

Respuestas interesantes pero los documentos dicen diferente:

Use los GetNumericValuemétodos para convertir un Charobjeto que representa un número en un tipo de valor numérico. Use Parsey TryParsepara convertir un carácter de una cadena en un Char objeto. Use ToStringpara convertir un Char objeto en un Stringobjeto.

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

Chad Grant
fuente
ahh! ¡Entonces hay algo nativo! Es extraño que devuelva un doble. Me gusta más esta respuesta. Gracias por mencionarlo.
KeithA
92
@KeithA: Hay una razón para que devuelva el doble: char.GetNumericValue('¼')produce 0.25. Las alegrías de Unicode ... ;-)
Heinzi
1
Esta no es una respuesta que responda a la pregunta real, Char.GetNumericValue ('o'), Char.GetNumericValue ('w') y cualquier carácter no numérico siempre devolverá -1 - Jeremy Ruten ha publicado la respuesta correcta
Rusty Nail
2
@RustyNail en el caso de la pregunta original - preguntando específicamente dónde sabe que el personaje representa un número - esta es la respuesta correcta
Don Cheadle
@mmcrae Yo no lo creo - la pregunta original pide chara intsin necesidad de utilizar stringpor primera vez.
NetMage
164

Esto lo convertirá en un int:

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

Esto funciona porque cada personaje está representado internamente por un número. Los caracteres '0' a '9' están representados por números consecutivos, por lo que encontrar la diferencia entre los caracteres '0' y '2' da como resultado el número 2.

Jeremy Ruten
fuente
55
Asume un cierto conjunto de caracteres.
EricSchaefer
8
No, no lo hace, siempre y cuando los dígitos estén en orden (que los compiladores requieren del juego de caracteres) funcionará, sin importar en qué valor comiencen.
Jeremy Ruten
2
Esto está bien, excepto que todavía necesita hacer una verificación de límites primero, y en ese momento no estoy seguro de si int.parse (foo.ToString ()) es más rápido.
Matthew Flaschen
77
@EricSchaefer Pero esa es una suposición segura en C #: charsiempre es UTF-16.
svick
2
@svick punto pequeño y antiguo ahora, pero en el tiempo transcurrido desde que publicó esto, salió Core, que usa UTF-8. Sin embargo, sigue siendo una suposición segura.
Joel Coehoorn
84

¿Alguien ha considerado usar int.Parse()y me int.TryParse()gusta esto?

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

Aún mejor así

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

Es mucho más seguro y menos propenso a errores

defectuoso
fuente
2
Absolutamente el enfoque correcto. Elija el primero si desea lanzar entradas que no sean int, el segundo si desea hacer otra cosa.
Jay Bazuzi
Este es un buen enfoque para un método de conversión genérico. Como comentario aparte, es otro ejemplo de cómo .NET promueve el bloatware. (Me refiero a continuar y probar TryParse () y ToString (), no puedes, prácticamente no).
cierre sesión el
55
@logout no, es un ejemplo de cómo una respuesta en StackOverflow promueve el bloatware. De hecho, esto está innecesariamente hinchado, y no entiendo por qué esto se considera superior a restar '0'del personaje.
Roman Starkov
26
char c = '1';
int i = (int)(c-'0');

y puedes crear un método estático a partir de él:

static int ToInt(this char c)
{
    return (int)(c - '0');
}
sontek
fuente
Esto es lo que estaba buscando. Tal vez podría explicar lo que está haciendo con la parte menos cero.
Xonatron
10

Prueba esto

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

int b = x - '0'; //That is '9' - '0' = 57 - 48 = 9
RollerCosta
fuente
Su comentario dice '9', pero su código tiene 9, que no se compilará.
svick
7

Por defecto, utiliza UNICODE, por lo que le sugiero que utilice el método defectuoso.

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

Aunque los valores numéricos debajo son los mismos para dígitos y caracteres latinos básicos.

Nikolay
fuente
4

Esto se convierte en un entero y maneja unicode

CharUnicodeInfo.GetDecimalDigitValue('2')

Puedes leer más aquí .

Dan Friedman
fuente
4

La forma real es:

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

"theNameOfYourInt": el int al que quieres que se transforme tu char.

"theNameOfYourChar": el Char que quieres usar para que se transforme en int.

Deja todo lo demás.

Normantas Stankevičius
fuente
2

Principio:

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

El binario de los caracteres ASCII 0-9 es:

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

y si toma en cada uno de ellos los primeros 4 LSB (usando bit a bit Y con 8'b00001111 que equivale a 15) obtendrá el número real (0000 = 0,0001 = 1,0010 = 2, ...)

Uso:

public static int CharToInt(char c)
{
    return 0b0000_1111 & (byte) c;
}
Tomer Wolberg
fuente
2
Si bien este fragmento de código puede ser la solución, incluir una explicación realmente ayuda a mejorar la calidad de su publicación. Recuerde que está respondiendo la pregunta para los lectores en el futuro, y que esas personas podrían no conocer los motivos de su sugerencia de código.
yivi
2

Estoy de acuerdo con @Chad Grant

También correcto si convierte a cadena, entonces puede usar ese valor tan numérico como se dice en la pregunta

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

Traté de crear un ejemplo más simple y comprensible

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

char.GetNumericValue (v) devuelve como doble y convierte a (int)

Uso más avanzado como una matriz

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

Comparación de algunos de los métodos basados ​​en el resultado cuando el carácter no es un 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
fuente
0

Estoy usando Compact Framework 3.5, y no tiene un método "char.Parse". Creo que no está mal usar la clase Convert. (Ver CLR a través de 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 con caracteres ASCII o caracteres Unicode

antonio
fuente
-4

Esto funcionó para mí:

int bar = int.Parse("" + foo);
Renán Díaz
fuente
55
¿Cómo es eso diferente int.Parse(foo.ToString()), excepto por ser menos legible?
svick
-5

He visto muchas respuestas pero me parecen confusas. ¿No podemos simplemente usar Type Casting?

Por ejemplo: -

int s;
char i= '2';
s = (int) i;
Aprendiz
fuente
1
Esto devolvería el código ASCII del carácter 2, no el valor 2.
cavpollo
Entonces, ¿qué hay de usar char.GetNumericValue (devuelve un valor doble) y convertirlo en int.
Estudiante
Sí, eso es lo que propone la respuesta aceptada de @Chad Grant
cavpollo