Jak przekonwertować ciąg na liczbę (Przewodnik programowania w języku C#)

Przekonwertujesz string element na liczbę, wywołując Parse metodę lub TryParse znajdującą się w typach liczbowych (int, long, doubleitd.) lub przy użyciu metod w System.Convert klasie .

Wywołanie TryParse metody (na przykład int.TryParse("11", out number)) lub Parse metody (na przykład ) jest nieco bardziej wydajne i proste (na przykład var number = int.Parse("11")). Użycie metody jest bardziej przydatne w przypadku obiektów ogólnych implementujących IConvertiblemetodę Convert .

Używasz Parse metod lub TryParse w typie liczbowym, który ma zawierać ciąg, na przykład System.Int32 typ. Metoda Convert.ToInt32 używa Parse wewnętrznie. Metoda Parse zwraca przekonwertowaną liczbę. TryParse Metoda zwraca wartość logiczną wskazującą, czy konwersja zakończyła się pomyślnie, i zwraca przekonwertowaną liczbę w parametrze out . Jeśli ciąg nie ma prawidłowego formatu, zgłasza wyjątek, Parse ale TryParse zwraca wartość false. Podczas wywoływania Parse metody należy zawsze używać obsługi wyjątków, aby przechwycić błąd, gdy operacja analizy zakończy się niepowodzeniem FormatException .

Wywoływanie metod Analizy lub TryParse

Metody Parse i TryParse ignorują białe znaki na początku i na końcu ciągu, ale wszystkie inne znaki muszą być znakami, które tworzą odpowiedni typ liczbowy (int, long, ulong, float, , decimalitd.). Wszelkie białe znaki w ciągu tworzącym liczbę powodują błąd. Na przykład można decimal.TryParse użyć metody , aby przeanalizować wartość "10", "10.3" lub "10", ale nie można użyć tej metody, aby przeanalizować 10 z "10X", "1 0" (zwróć uwagę na osadzoną przestrzeń), "10 .3" (zwróć uwagę na osadzoną przestrzeń), "10e1" (float.TryParse działa tutaj) itd. Ciąg, którego wartość jest null lub String.Empty nie można przeanalizować pomyślnie. Aby przeanalizować ciąg o wartości null lub pusty, możesz go sprawdzić, wywołując metodę String.IsNullOrEmpty .

W poniższym przykładzie pokazano zarówno pomyślne, jak i nieudane wywołania metod Parse i TryParse.

using System;

public static class StringConversion
{
    public static void Main()
    {
        string input = String.Empty;
        try
        {
            int result = Int32.Parse(input);
            Console.WriteLine(result);
        }
        catch (FormatException)
        {
            Console.WriteLine($"Unable to parse '{input}'");
        }
        // Output: Unable to parse ''

        try
        {
            int numVal = Int32.Parse("-105");
            Console.WriteLine(numVal);
        }
        catch (FormatException e)
        {
            Console.WriteLine(e.Message);
        }
        // Output: -105

        if (Int32.TryParse("-105", out int j))
        {
            Console.WriteLine(j);
        }
        else
        {
            Console.WriteLine("String could not be parsed.");
        }
        // Output: -105

        try
        {
            int m = Int32.Parse("abc");
        }
        catch (FormatException e)
        {
            Console.WriteLine(e.Message);
        }
        // Output: Input string was not in a correct format.

        const string inputString = "abc";
        if (Int32.TryParse(inputString, out int numValue))
        {
            Console.WriteLine(numValue);
        }
        else
        {
            Console.WriteLine($"Int32.TryParse could not parse '{inputString}' to an int.");
        }
        // Output: Int32.TryParse could not parse 'abc' to an int.
    }
}

Poniższy przykład ilustruje jedno podejście do analizowania ciągu oczekiwanego do uwzględnienia wiodących znaków liczbowych (w tym znaków szesnastkowych) i końcowych znaków nieliczbowych. Przypisuje prawidłowe znaki od początku ciągu do nowego ciągu przed wywołaniem TryParse metody . Ponieważ ciągi do przeanalizowania zawierają kilka znaków, przykład wywołuje String.Concat metodę w celu przypisania prawidłowych znaków do nowego ciągu. W przypadku większego ciągu StringBuilder można zamiast tego użyć klasy .

using System;

public static class StringConversion
{
    public static void Main()
    {
        var str = "  10FFxxx";
        string numericString = string.Empty;
        foreach (var c in str)
        {
            // Check for numeric characters (hex in this case) or leading or trailing spaces.
            if ((c >= '0' && c <= '9') || (char.ToUpperInvariant(c) >= 'A' && char.ToUpperInvariant(c) <= 'F') || c == ' ')
            {
                numericString = string.Concat(numericString, c.ToString());
            }
            else
            {
                break;
            }
        }

        if (int.TryParse(numericString, System.Globalization.NumberStyles.HexNumber, null, out int i))
        {
            Console.WriteLine($"'{str}' --> '{numericString}' --> {i}");
        }
        // Output: '  10FFxxx' --> '  10FF' --> 4351

        str = "   -10FFXXX";
        numericString = "";
        foreach (char c in str)
        {
            // Check for numeric characters (0-9), a negative sign, or leading or trailing spaces.
            if ((c >= '0' && c <= '9') || c == ' ' || c == '-')
            {
                numericString = string.Concat(numericString, c);
            }
            else
            {
                break;
            }
        }

        if (int.TryParse(numericString, out int j))
        {
            Console.WriteLine($"'{str}' --> '{numericString}' --> {j}");
        }
        // Output: '   -10FFXXX' --> '   -10' --> -10
    }
}

Wywoływanie metod konwertuje

W poniższej tabeli wymieniono niektóre metody z Convert klasy, których można użyć do przekonwertowania ciągu na liczbę.

Typ liczbowy Method
decimal ToDecimal(String)
float ToSingle(String)
double ToDouble(String)
short ToInt16(String)
int ToInt32(String)
long ToInt64(String)
ushort ToUInt16(String)
uint ToUInt32(String)
ulong ToUInt64(String)

Poniższy przykład wywołuje metodę w Convert.ToInt32(String) celu przekonwertowania ciągu wejściowego na int. W przykładzie opisano dwa najbardziej typowe wyjątki zgłaszane przez tę metodę: FormatException i OverflowException. Jeśli wynikowa liczba może być zwiększana bez przekroczenia Int32.MaxValuewartości , przykład dodaje 1 do wyniku i wyświetla dane wyjściowe.

using System;

public class ConvertStringExample1
{
    static void Main(string[] args)
    {
        int numVal = -1;
        bool repeat = true;

        while (repeat)
        {
            Console.Write("Enter a number between −2,147,483,648 and +2,147,483,647 (inclusive): ");

            string? input = Console.ReadLine();

            // ToInt32 can throw FormatException or OverflowException.
            try
            {
                numVal = Convert.ToInt32(input);
                if (numVal < Int32.MaxValue)
                {
                    Console.WriteLine("The new value is {0}", ++numVal);
                }
                else
                {
                    Console.WriteLine("numVal cannot be incremented beyond its current value");
                }
           }
            catch (FormatException)
            {
                Console.WriteLine("Input string is not a sequence of digits.");
            }
            catch (OverflowException)
            {
                Console.WriteLine("The number cannot fit in an Int32.");
            }

            Console.Write("Go again? Y/N: ");
            string? go = Console.ReadLine();
            if (go?.ToUpper() != "Y")
            {
                repeat = false;
            }
        }
    }
}
// Sample Output:
//   Enter a number between -2,147,483,648 and +2,147,483,647 (inclusive): 473
//   The new value is 474
//   Go again? Y/N: y
//   Enter a number between -2,147,483,648 and +2,147,483,647 (inclusive): 2147483647
//   numVal cannot be incremented beyond its current value
//   Go again? Y/N: y
//   Enter a number between -2,147,483,648 and +2,147,483,647 (inclusive): -1000
//   The new value is -999
//   Go again? Y/N: n