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

2011-09-04 11:12
BioZ
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.

Pozostało 580 znaków

2011-09-04 13:02
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ą.


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."
edytowany 1x, ostatnio: somekind, 2011-09-04 13:04

Pozostało 580 znaków

2011-09-04 13:20
BioZ
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 wkurwi, 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ą.

Pozostało 580 znaków

2011-09-04 18:11
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?


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."
problem się robi, gdy chcesz liczby wczytywać z pliku ze z góry ustalonym formatem, lub zapisywać do pliku np. konfiguracyjnego. - Azarien 2011-09-04 22:47
No tak, ale tu o wpisywaniu z klawiatury mowa. - somekind 2011-09-04 23:17

Pozostało 580 znaków

2011-09-04 19:06
BioZ
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 ;).

Pozostało 580 znaków

2011-09-04 19:14
Rev
0

Budowanie funkcji w C# w oparciu o

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

MISTRZ.


Pozostało 580 znaków

2011-09-04 19:32
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();
edytowany 1x, ostatnio: Azarien, 2011-09-04 19:32

Pozostało 580 znaków

2011-09-04 19:43
BioZ
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?

Osoba, od której skopiowałeś też .NET Frameworka nie znała. - Rev 2011-09-04 19:58

Pozostało 580 znaków

Liczba odpowiedzi na stronę

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