views:

167

answers:

5

I have a string:

string test = "19,95";

and I wan't to convert it to an int.

I use:

int num = Convert.Int32(test);

However it throws an FormatException. And tells me that the string is not a proper string for conversion.

My guess is that it has to do with the decimal seperator.

How do i work around this?

+3  A: 
string dblText = "19,95";
CultureInfo ci = new CultureInfo ("en-US", true);
ci.NumberFormat.NumberDecimalSeparator = ",";
double dblValue = double.Parse (dblText, NumberStyles.AllowDecimalPoint, ci);

If you need 19 (casting off the decimal part):

int intValue = (int)dblValue;

If you need 20 (mathematical rounding):

int intValue = (int)(dblValue + 0.5);
Developer Art
This would still fail if the localisation was wrong. The string has a comma separator - probably indicating European orgin. If you ran this with a UK or US localisation setting it would fail as it expects a full stop as a separaor. The comma is a thousand separator for UK/US
Paul Hadfield
Just a note to anyone reading: This answer has since been edited. Question: Why create a new culture that's a variant of en-US? That's just messing up the semantics. 'da' or 'da-DK' seem far more appropriate - and don't require you to create a whole new culture!
Rushyo
It was just a quick solution to suggest the idea. I like more the solution from hydrogen.
Developer Art
+1  A: 

What integer would you expect to get from "19,95"? 1995? 19? 20?

Perhaps you should convert the number to a double first, and then round or truncate in whichever direction makes sense for your application.

sarnold
A: 

are you sure you want it to be an int?

this number is a double.

int num = (int)double.Parse(test); //will be 19

double num = double.Parse(test); //wil be 19.95
Stefanvds
why do an int.Parse to a double value when you could do double.Parse?
Joakim
Decimal separator must be `.`
Cipi
Who said? Plenty of countries that use a , would disagree.
hydrogen
+3  A: 
using System.Globalization;
...
NumberFormatInfo nfi = new NumberFormatInfo();
nfi.NumberDecimalSeparator = ",";
double num = Convert.ToDouble(test, (IFormatProvider)nfi);

Tested & working.

For completeness:

int applesApplesApples = Math.Ceiling(num);
int bananaBananaBanana = (int)num;
int cucumberCucumberCucumber = Math.Floor(num);

[Update]

As Rushyo correctly pointed out in my comments below, this example is contrived and the best practice approach is to identify which culture you are working with in order to get the correct CultureInfo object to work off of.

You can then utilize the localized NumberFormatInfo from that specific CultureInfo when doing all your numeric formatting.

hydrogen
Henk Holterman
Why do you want an int.. Someone is going to feel really ripped off if you just rounded their $19,95 up to $20 and didn't give them their 5c change. I have a slight feeling that the OP might have got his types muddled. In any case, I will leave it up to the OP to figure the next bit out if he really does want an int.
hydrogen
I wan't the int. My working solution right now is to use split to remove the comma and everything after it. Then the convert works. This however also results in the number being rounded down, i want the proper rounding up or down.
Bildsoe
Cool, do as above (converting to double first) then use: int intVal = (int)doubleVal; to get yourself an int rounded to the nearest integer.
hydrogen
Use Math.Round. Much, much more consistent (cast the result to an int)
Rushyo
NOTE: Really not a fan on this solution. .NET has excellent localisation features. Utilising the Danish CultureInfo is going to save you alot of headaches. The classes are there. Use them!
Rushyo
@Rushyo, Yeah you're right, supporting localization is definately good practice. The contrived example above could be quickly adapted to support this by just extracting the appropriate NumberFormatInfo from your localized CultureInfo.
hydrogen
+1  A: 

As the others already mentioned the main problem of your question is, that you don't gave any information about what result you expect and some also brought up the problem with the Culture (decimal separator, thousand separator). So i will make a little sum up:

private int Parse(string text)
{
    Decimal value;

    //Select the culture you like to use
    var culture = CultureInfo.CurrentCulture;
    //var culture = CultureInfo.GetCultureInfo("en-US");
    //var culture = CultureInfo.GetCultureInfo("de-DE");

    if (Decimal.TryParse(text, NumberStyles.Number, culture, out value))
    {
        //Throw away the fractional part
        //return (int)value;

        //or make some rounding??
        return (int)Math.Round(value, MidpointRounding.ToEven);
    }

    //What should happen if the parsing fails??
    //Return some default value
    return int.MinValue;
    //return 0;

    //Or throw an exception?
    //throw new FormatException();
    //In that case, maybe use directly Decimal.Parse and let this
    //function throw the exception with the correct message.
}
Oliver