C++ Builder 6, program działa w inny sposób na innym PC

0

Cześć,
jestem w trakcie pisania małego programu w C++ Builder. Ogólnie to polega na tym, że użytkownik podaje dane (liczby zmiennoprzecinkowe) a program przelicza i wyświetla wynik. Oprócz tego, aby nie dało się zrobić głupot jest kilka "sprawdzajek" czy wszystko jest jak należy.

Mam tam m.in. takie elementy:

        //pobiera dane z pola, zmienia kropkę na przecinek, potrzebne do konwersji string do double
        temp = pole->Text.c_str();
        std::replace( temp.begin(), temp.end(), '.', ',');
        pole -> Text = temp.c_str();
        //sprawdza czy wpisane dane można konwertować do float
        if( !TryStrToFloat(pole->Text, value) )
        {
        Error1 -> Visible = True;
        pole->SetFocus();
        return;
        }
        //jeśli dane w polach są mniejsze lub równe zero to wyrzuca błąd
        if (pole1 -> Text.ToDouble() <= 0 || pole2 -> Text.ToDouble() <= 0 || pole3 -> Text.ToDouble() <= 0 || pole4 -> Text.ToDouble() <= 0 || pole5 -> Text.ToDouble() <= 0)
                        Error1 -> Visible = true;

Potem idą już same obliczenia a na końcu obliczone wartości wyświetlane są w polach na wyniki. Niby wszystko ładnie i ok, ale pojawia się problem. Na dwóch PC na których sprawdzałem jest ok. Program liczy jak trzeba, wszystko przechodzi itd. Natomiast na komputerze kumpla wprowadzenie liczby innej niż całkowita powoduje, że któraś "sprawdzajka" nie przechodzi i wywołuje okno Error1. Oczywiscie tak on jak i ja sprawdziliśmy na tym samym skomplikowanym exe, sprawdzałem z tymi danymi co on i było dobrze. On sprawdzał na innym pc i też śmiga. Skąd więc błąd na tym konkretnym pc?

1

Zastanawia mnie to Error1 -> Visible = True;, nie pamiętam dokładnie jak to jest w Builderze, ale raczej tak samo jak w zwykłym C++, więc true powinno być z małej litery :)

0

W teorii tak, w praktyce zauważyłem że akurat tu mu nie robi różnicy. Ale i tak zmienię żeby było poprawnie.

2
//pobiera dane z pola, zmienia kropkę na przecinek, potrzebne do konwersji string do double

Nie nie nie. Masz DecimalSeparator który definiuje prawidłowy znak separatora.

1

Jak na moje oko to problem tkwi w nieczytaniu dokumentacji ;)

A tak na poważnie, wskaźnik uzyskany w wyniku wywołania metody c_str() nie powinien służyć do modyfikacji stringa.

link do dokumentacji

The c_System::c_str method is intended primarily for reading the value of the System::AnsiString. To modify the System::c_string’s value, use the [] operator or System::AnsiString methods such as Insert and Delete.

Co więcej podczas każdej zmiany stringa wskaźnik zwracany przez tą metodę może być inny

Usually, the value returned by c_System::c_str points to the internal character array referenced by the data property. This pointer is valid until the System::c_string is next modified (for example when the SetLength method is called or the System::AnsiString goes out of scope).

Co więcej moim zdanie po co korzystać z metod std do operowaniu na stringach skoro już są takie udostępnianie przez sam moduł VCL dla klasy AnsiString. kolejny link

Nie mówiąc już o tym o czym wspominał @Azarien, czyli np. użycie metody umożliwiającej konwersję z użyciem przecinka jako separatora do której można przekazać odpowiednie zmienne.

0

Mogę prosić o jakiś przykład z tym DecimalSeparator albo gdzie coś o tym znaleźć? Bo nie znalazłem, chyba że mówicie o tym:
http://www.cplusplus.com/reference/locale/numpunct/decimal_point/

Wiem też że sposób w jaki to napisałem jest mało elegancki, ale spełniał swoje zadanie a potrzebowałem coś na szybko. Pierwotnie planowałem zrobić po prostu regex ale biblioteka która doinstalowalem nie chciała się załączyć.

1

Ja mam na myśli to:

TFormatSettings fs = TFormatSettings();
fs.DecimalSeparator = ',';
double Liczba;
Liczba = StrToFloat(Edit1->Text,fs);

Po więcej kliknij tu

Zaś zamiana kropi na przecinek:

AnsiString temp = StringReplace(Edit1->Text,".",",",TReplaceFlags() << rfReplaceAll);
0

Dzięki, będę patrzył na to jutro.

0

Dobra, więc doszedłem do tego skąd był błąd. Ot u mnie program za znak dziesiętny program uznaje "," a na PC na którym nie działało uznaje "."

DecimalSeparator=',';

Separator ustawiony jak wyżej i śmiga. Reszta również zmieniona za waszymi radami. Bardzo dziękuję za pomoc.

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