2009-11-05 40 views
9

¿Cómo evito que el siguiente código arroje un FormatException. Me gustaría poder analizar cadenas con un cero inicial en enteros. ¿Hay una manera limpia de hacer esto?int.Parse() con ceros a la izquierda

string value = "01"; 
int i = int.Parse(value); 
+1

Su código de ejemplo funciona muy bien para mí (si cambio a analizar Analizar). –

+0

puede usar 'int.Parse (value, Culture.InvariantCulture)' – Sebastian

+0

A menudo un cero delante significa que el número está en Octal (base 8). ¿La cadena '" 020 "' pretende ser '20' (base 10) o' 16' (base 10)? – Dai

Respuesta

18

Su código se ejecuta para mí, sin FormatException (una vez a capitalizar el método correctamente):

string value = "01"; 
int i = int.Parse(value); 

pero esto suena un timbre de edad; un problema que tuve hace años, que Microsoft aceptó como un error contra los componentes de localización de Windows (no .NET). Para probar si estás viendo esto, ejecute este código y nos permiten saber si se obtiene una FormatException:

string value = "0"; // just a zero 
int i = int.Parse(value); 

EDITAR: aquí está mi puesto de Usenet, de nuevo en 2007. A ver si los síntomas coinciden con los suyos .

Como referencia, esto es lo que encontramos. La máquina afectada tenía datos incorrectos para el valor de registro [HKEY_CURRENT_USER \ Panel de control \ International \ sPositiveSign]. Normalmente, este valor es un REG_SZ vacío (cadena terminada en nulo). En este caso, a la cadena le faltaba su terminador . Esto confundió la función de API GetLocaleInfoW(), causando que pensara que '0' (número cero ASCII) era el signo positivo para el escenario actual (normalmente debería ser '+'). Esto causó todo tipo de estragos.

Esto se puede comprobar por sí mismo con regedit.exe: abrir ese valor reg por el botón derecho sobre el valor y seleccionar 'Modificar datos binarios'. Usted debe ver dos puntos a la derecha (que representa el terminador nulo). Si no ve puntos, se verá afectado. Solucionarlo agregando un terminador (cuatro ceros ).

También puede consultar el valor de CultureInfo.CurrentCulture.NumberFormat.PositiveSign; debe ser '+'.

Es un error en la localización de Windows API, no en las librerías de clase. El valor reg debe verificarse para un terminador . Lo están mirando.

... y here's a report on Microsoft Connect sobre el tema:

+0

Estoy de acuerdo: a mi me funciona, también –

1

Trate

int i = Convert.ToInt32 (valor);

Editar: Hmm. Como se señaló, solo está envolviendo Int32.Parse. No estoy seguro de por qué está recibiendo FormatException, independientemente.

+1

¿Qué hace Convert.ToInt32 de manera diferente que int.parse? –

+1

Convert.ToInt16 y Convert.ToInt64, es en realidad un método de envoltura estático para el método int.Parse. Puede ser más lento que int.Parse si el código circundante es equivalente. – Nescio

+0

@Taylor: Puede consultar con .Net Reflector –

4

TryParse le permitirá confirmar el resultado del análisis sintáctico sin lanzar una excepción.Para citar a MSDN

Convierte la representación de cadena de un número a sus 32 bits entero de equivalente. Un valor de retorno indica si la operación fue exitosa.

Para utilizar su ejemplo

private static void TryToParse(string value) 
    { 
     int number; 
     bool result = Int32.TryParse(value, out number); 
     if (result) 
     { 
     Console.WriteLine("Converted '{0}' to {1}.", value, number);   
     } 
     else 
     { 
     if (value == null) value = ""; 
     Console.WriteLine("Attempted conversion of '{0}' failed.", value); 
     } 

}

4
int i = int.parse(value.TrimStart('0')); 
+0

Me gusta este enfoque para eludir los problemas locales/básicos. ¡Pero creo que voy a editar la respuesta debido al caso de valor-es-solo-0 caracteres! – jmnben

1

Usted no tiene que hacer nada en absoluto. Agregar ceros a la izquierda no causa una FormatException.

Para estar 100% seguro de que probé su código, y después de corregir parse a Parse funciona perfectamente y no lanza ninguna excepción.

Obviamente no está mostrando el código real que está utilizando, por lo que es imposible decir dónde está el problema, pero definitivamente no es un problema para el método Parse para manejar los ceros a la izquierda.

7

Trate

int i = Int32.Parse(value, NumberStyles.Any); 
1

tengo los siguientes códigos que pueden ser útiles:

int i = int.Parse(value.Trim().Length > 1 ? 
    value.TrimStart(new char[] {'0'}) : value.Trim()); 

Esto Se quita todos 0s principales adicionales y evitar el caso de un solo 0.

0

Para un número decimal:

Convert.ToInt32("01", 10); 
// 1 

Por unos números de 16 bits, donde los ceros iniciales son comunes:

Convert.ToInt32("00000000ff", 16); 
// 255 
Cuestiones relacionadas