views:

117

answers:

6

What is the best way to take a string which can be empty or contain "1.2" for example, and convert it to an integer? int.TryParse fails, of course, and I don't want to use float.TryParse and then convert to int.

Thanks!

+1  A: 

Maybe you can try to delete everything after floating point using string functions and then convert to int. But seriously I don't think it's better than converting to float and then to int.

fuwaneko
If you do it that way, don't forget that the decimal delimiter is different on different regional settings. Our French cousins use `,`
MarkJ
Of course, I thought it was obvious :) In Russia we use commas as well.
fuwaneko
+6  A: 
var a = (int)Convert.ToDouble("1.2");    

Note if you're using comma as a number separator in your operating system, you have to use IFormatProvider:

var a = (int)Convert.ToDouble("1.2", CultureInfo.InvariantCulture.NumberFormat); 

Another way to accomplish this task:

var a = int.Parse("1.2".Split('.')[0]);

Remember about:

ventr1s
+1. Especially for saying that `Convert.ToDouble` uses the decimal delimiter from the thread culture settings (by default the Windows regional settings), and it can be a comma. You can force it to use a dot by passing `CultureInfo.InvariantCulture.NumberFormat`
MarkJ
+2  A: 

I don't know what's wrong with parsing to a float and converting to an int. I doubt that any other way would be more efficient but here's an attempt:

//allows empty strings and floating point values
int ParseInt(string s, bool alwaysRoundDown = false)
 {
    //converts null/empty strings to zero
    if (string.IsNullOrEmpty(s)) return 0;

    if (!s.Contains(".")) return int.Parse(s);

    string parts = s.Split(".");
    int i = int.Parse(parts[0]);
    if (alwaysRoundDown || parts.Length==1) return i;

    int digitAfterPoint = int.Parse(parts[1][0]);
    return (digitAfterPoint < 5) ? i : i+1;
 }

In order to globalize the code you would need to replace "." with System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator.

Mark Cidade
Don't forget that the decimal delimiter can be different depending on regional settings.
MarkJ
I added a note about globalization. Thanks!
Mark Cidade
Undoubtedly the best one, @Mark. +1 from my side.
Kangkan
A: 

I think another way of doing it would be splitting the string into pieces taking the decimal (.) as the delimiter and then parsing for the integer. Of course, I am yet to ask you if the string might contain values like "37.56 miles in 32.65 seconds" type values.

Considering there will be only one value (string or number) in the string, I can think of something in the following line:

public int64 GetInt64(string input)
{
    if (string.IsNullOrEmpty(input)) return 0;
    // Split string on decimal (.)
    // ... This will separate all the digits.
    //
    string[] words = input.Split('.');
    return int.Parse(words[0]);
}
Kangkan
Perhaps no need for int64 return when doing an int32 parse.
btlog
A: 
int a = (int)Math.Round(float.Parse("0.9"));

You need to round it first unless you want 0.9f being converted to 0 instead of 1.

Struan
A: 

You can use the Visual Basic runtime Library to accomplish this from c#.

You need to add a reference to the assembly Microsoft.VisualBasic.dll to your solution.

Then the following code will do your conversion:

using VB = Microsoft.VisualBasic.CompilerServices;

class Program
{
    static void Main(string[] args)
    {
        int i = VB.Conversions.ToInteger("1.2");
    }
}
David