Przecinek zamiast kropki w double.Parse() i liczba wyświetlanych cyfr po przecinku

0

Witam,

Nie mogąc doszukać się, czy istnieje funkcja która pozwala maksymalnie ograniczyć użytkownika we wprowadzaniu danych w konsoli (w celu zwiększenia idiotoodporności) napisałem własną. Początkowo była ona w C++ i wszystko było ok, ale musiałem mój program przepisać na C# i teraz dostaję FormatException z wiadomością "Input string was not in a correct format" gdy na przykład wpisuję "0.222".

Kod metody:

        [DllImport("msvcrt")]
        static extern int _getch();

//(...)

        private static double GetValue(bool getDouble) //pobiera zmienna int lub double od uzytkownika - +1 do idiotoodpornosci
        {
            string temp = "";
            int znak;
            int z = 0;
            int dots = 0;

            do
            {
                if (z == 9) //limit znakow
                {
                    znak = _getch();
                    if (znak == 8) //bksp
                    {
                        z--;
                        Console.Write("\b \b");
                        if (getDouble && temp[z] == 46)
                                dots--;
                        temp = temp.Remove(temp.Length - 1, 1);
                    }
                }
                else
                {
                    znak = _getch();
                    if ((z > 0) && (znak == 8))
                    {
                        z--;
                        Console.Write("\b \b");
                        if (getDouble && temp[z] == 46)
                            dots--;
                        temp = temp.Remove(temp.Length - 1, 1);
                    }
                    if (getDouble)
                    {
                        if ((znak >= 48) && (znak <= 57) || (znak == 46 && dots == 0))
                        {
                            if (znak == 46)
                                dots++;

                            temp += (char)znak;
                            Console.Write((char)znak);
                            z++;
                        }
                    }
                    else
                    {
                        if ((znak >= 48) && (znak <= 57))
                        {
                            temp += (char)znak;
                            Console.Write((char)znak);
                            z++;
                        }
                    }
                }
            } while (znak != '\r'); //enter

            double result = double.Parse(temp); //tu wystepuje wyjatek
            if (result > 0)
                return result;

            return -1;
        }

Zauważyłem, że problemem jest podawanie kropki a nie przecinka. Czy można gdzieś ustawić, że akceptowana i wyświetlana w powiązaniu z double ma być kropka a nie przecinek?

Jeszcze jedno pytanie przy okazji, w C++ setprecision określał liczbę miejsc po przecinku, ale w razie mniejszej liczby miejsc znaczących w danej zmiennej kończył wraz z nimi, natomiast teraz jak używam:

String.Format("{0:F6}", costam)

To nawet jak zmienna została podana jak całkowita (150,0), to wyświetla niepotrzebne zera po przecinku. Jak to obejść?

Pozdrawiam.

P.S. Pytanie pierwsze jest trochę "pro forma", bo nie ma znaczenia czy to będzie przecinek czy kropka. Zdziwiło mnie tylko, że wbrew moim domysłom na temat stosowania kropki i przecinka tak jest.

0

Co Ty w ogóle kombinujesz?

Po pierwsze, pobranie liczby można zrobić tak:

static void Main(string[] args)
{
    double d;
    bool ok = false;

    do
    {
        Console.WriteLine("Podaj liczbę");
        string s = Console.ReadLine();

        ok = double.TryParse(s, out d);
        if (ok)
        {
            Console.WriteLine("Brawo, podałeś liczbę!");
        }
        else
        {
            Console.WriteLine("To nie jest liczba!");
        }
    } while (!ok);

    Console.WriteLine("Podałeś: {0}", d);
    Console.ReadLine();
}

Po drugie w Polsce separatorem dziesiętnym jest przecinek, a nie kropka. Jeśli chcesz wymusić na użytkownikach podawanie kropki (nie wiem tylko po co, chyba tylko, żeby kogoś wkurwić), to można to zrobić korzystając z przeciążonej wersji metody Parse lub TryParse przyjmujących IFormatProvider, np.:

 
double d = double.Parse("123,543.87", CultureInfo.InvariantCulture); //d = 123 543,87

Sugerowałbym poczytanie jakiegoś kursu lub książki, bo konwersja napisów na liczby to nie jest coś, co trzeba robić po swojemu, wystarczy dowiedzieć się, które metody za to odpowiadają.

0

Po drugie w Polsce separatorem dziesiętnym jest przecinek, a nie kropka. Jeśli chcesz wymusić na użytkownikach podawanie kropki (nie wiem tylko po co, chyba tylko, żeby kogoś wkurwić)

Przeczytaj P.S.
Poza tym, że przyzwyczaiłem się do wpisywania kropki i jestem jedynym użytkownikiem programu, więc nikt się nie troszeczkę zdenerwuje, to po nic.
Nie spodziewałem się, że C# jest "zlokalizowany" w tym sensie.

Sugerowałbym poczytanie jakiegoś kursu lub książki, bo konwersja napisów na liczby to nie jest coś, co trzeba robić po swojemu, wystarczy dowiedzieć się, które metody za to odpowiadają.

Spoko, jeszcze myślę w niższym poziomie.

P.S. Dziękuję za sugestię, swoją drogą.

0
BioZ napisał(a)

Nie spodziewałem się, że C# jest "zlokalizowany" w tym sensie.

C#, a właściwie .NET korzysta z ustawień regionalnych komputera w wielu miejscach. Dzięki temu raz napisana aplikacja nie wymaga żadnych modyfikacji do działania z innymi ustawieniami regionalnymi. W Polsce wpisze się "1 234,56", a w USA "1,234.56", zaś dla programu to będzie i tak to samo.

Poza tym, że przyzwyczaiłem się do wpisywania kropki

Z ciekawości - masz ustawioną angielską klawiaturę i kropka na numerycznej wstawia Ci kropkę, a nie przecinek?

0

Dobrze wiedzieć o własnościach .NET, dzięki.

Niestety, zwykle korzystam z laptopa na którym niewygodne jest korzystanie z numerycznej (która wstawia przecinek). Natomiast pisząc kilka lat w Matlabie i C++ na studiach - przyzwyczaiłem się do kropki ;).

0

Budowanie funkcji w C# w oparciu o

[DllImport("msvcrt")]
static extern int _getch();

MISTRZ.

0

Budowanie funkcji w C# w oparciu o
[DllImport("msvcrt")]
static extern int _getch();

jest to błąd, i wysypie się w przypadku dowolnej funkcji z parametrami. powinno być:

[DllImport("msvcrt", CallingConvention=CallingConvention.Cdecl)]
static extern int _getch();

a tak w ogóle to

Console.ReadKey();
0

Dzięki, poprawię (choć i tak skłaniam się ku funkcji przytoczonej przez Somekind, choć ona nie blokuje wprowadzania zastrzeżonych znaków i długości wprowadzonego stringa). Skopiowałem to z jakiegoś wątku na temat użycia getch() w C#, bo jeszcze na tyle nie znam .NET Frameworka.

Co do mistrza - przecież piszę w dziale Newbie, o co chodzi?

1 użytkowników online, w tym zalogowanych: 0, gości: 1