2009-11-05 5 views
9

Comment empêcher le code ci-dessous de lancer un FormatException. J'aimerais être capable d'analyser les chaînes avec un zéro en tête en ints. Existe-t-il un moyen propre de faire cela?int.Parse() avec des zéros en tête

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

Votre exemple de code fonctionne très bien pour moi (si je change d'analyser parser). –

+0

peut-être utiliser 'int.Parse (value, Culture.InvariantCulture)' – Sebastian

+0

Souvent, un zéro initial signifie que le nombre est en octal (base 8). La chaîne '" 020 "' est-elle censée être '20' (base 10) ou' 16' (base 10)? – Dai

Répondre

18

Votre code est exécuté pour moi, sans FormatException (une fois que vous capitalisez la méthode appropriée):

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

Mais cela ne sonne une vieille cloche; un problème que j'avais il y a des années, que Microsoft a accepté comme un bug contre les composants de localisation de Windows (pas .NET). Pour vérifier si vous voyez cela, exécutez ce code et laissez-nous savoir si vous obtenez un FormatException:

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

EDIT: voici mon post de Usenet, de retour en 2007. Voir si les symptômes correspondent aux vôtres .

Pour référence, voici ce que nous avons trouvé. La machine affectée avait des données incorrectes pour la valeur de registre [HKEY_CURRENT_USER \ Control Panel \ International \ sPositiveSign]. Normalement, cette valeur est vide REG_SZ (chaîne terminée par un caractère nul). Dans ce cas, il manquait à la chaîne son terminateur . Cela a confondu la fonction API GetLocaleInfoW(), l'amenant à penser que '0' (numéro ASCII zéro) était le signe positif pour l'environnement local (il devrait normalement être '+'). Cela a causé toutes sortes de ravages.

Vous pouvez vérifier par vous-même avec regedit.exe: ouvrir cette valeur reg par clic droit sur la valeur et en sélectionnant «Modifier les données binaires. Vous devriez voir deux points sur la droite (représentant le terminateur null). Si vous ne voyez aucun point, vous êtes affecté. Fixez-le en ajoutant un terminateur (quatre zéros ).

Vous pouvez également vérifier la valeur de CultureInfo.CurrentCulture.NumberFormat.PositiveSign; il devrait être '+'.

C'est un bogue dans l'API de localisation Windows , pas les bibliothèques de classe. La valeur reg doit être vérifiée pour un terminateur . Ils le regardent.

... et here's a report on Microsoft Connect sur la question:

+0

D'accord - cela fonctionne bien pour moi, aussi –

1

Essayez

int i = Convert.ToInt32 (valeur);

Modifier: Hmm. Comme souligné, il est juste envelopper Int32.Parse. Vous ne savez pas pourquoi vous obtenez le FormatException, malgré tout.

+1

Que fait Convert.ToInt32 différemment que int.parse? –

+1

Convert.ToInt16 et Convert.ToInt64, est en fait une méthode d'encapsulation statique pour la méthode int.Parse. Il peut être plus lent que int.Parse si le code environnant est équivalent. – Nescio

+0

@Taylor: Vous pouvez vérifier avec .Net Reflector –

4

TryParse vous permettra de confirmer le résultat de l'analyse syntaxique sans lancer une exception.Pour citer MSDN

convertit la représentation de chaîne de un nombre à son entier signé 32 bits équivalent. Une valeur de retour indique si l'opération a réussi.

Pour utiliser leur exemple

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

J'aime cette approche pour contourner les problèmes locaux/de base. Mais je pense que je vais éditer la réponse à cause du cas de caractères value-is-just-0! – jmnben

1

Vous ne devez rien faire du tout. L'ajout de zéros en tête ne provoque pas d'exception au format.

Pour être sûr à 100% que j'ai essayé votre code, et après avoir corrigé parse à Parse il fonctionne très bien et ne jette aucune exception.

De toute évidence, vous ne montrez pas le code réel que vous utilisez, il est donc impossible de dire où est le problème, mais ce n'est certainement pas un problème pour la méthode Parse pour gérer les zéros en tête.

7

Essayez

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

Je les codes suivants qui peuvent être utiles:

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

Cela couper tous les principaux 0s supplémentaires et éviter le cas d'un seul 0.

0

Pour un nombre décimal:

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

Pour un 16 nombre de bits, où des zéros non significatifs sont communs:

Convert.ToInt32("00000000ff", 16); 
// 255 
Questions connexes