Problem z StrToFloat w C++ Builder XE

0

Otóż mam dziwny problem z RAD Studio.
Mam na formularzu button i edit i chcę przypisać do zmiennej typu double wartość pola edit poprzez kliknięcie buttona. Wygląda to mnie więcej tak.

try
{
    	double a;
	a=StrToFloat(Edit1->Text);
}
catch(...)
{
        ShowMessage("Nie wszystkie pola zostały wypełnione poprawnie.");
}

W pole edit wpisuję powiedzmy: 4.3123
Na moim komputerze to działa - przypisuje bez problemu. Problem w tym, że na innych komputerach, gdzie nie ma RAD Studio rzuca Exception'a. Może mi ktoś powiedzieć co robię nie tak?

0

Za pewne kwestią jest separator dziesiętny. W Polsce stosuje się "," jednak standardem jest ".".

0

A jak go użyć?

#include <SYSUTILS.HPP>
extern char DecimalSeparator;

To oczywiście dodałem, ale jak chcę oprogramować zdarzenie onCreate dla Form1 w sposób:
DecimalSeparator = '.';

Ale wtedy...
Ambiguity between 'DecimalSeparator' and 'Sysutils::DecimalSeparator'

0

Normalnie dajesz w OnCreate

DecimalSeparator = '.';

i tyle .
Po co to extern char DecimalSeparator = '.'; ?

0

Kiedy się tak nie da :(

[BCC32 Fatal Error] interpolacja.cpp(343): F1004 Internal compiler error at 0x1e4574f1 with base 0x1e450000

0
DecimalSeparator = ',';
Application->UpdateFormatSettings = false ;
double a = StrToFloat(Edit1->Text);

Teraz winno działać.

0

Nie, dalej to samo...

 
        #include <SYSUTILS.HPP>

        ....

	double a;
	AnsiString x1,x2;
	DecimalSeparator = ',';
	Application->UpdateFormatSettings = false ;
	a=StrToFloat(Edit3->Text);
0

Możesz podać całość kodu i przykładowe dane wejściowe, które powodują u Ciebie problemy?

0

U mnie problemów nie ma żadnych, tylko na innym kompie z rad studio przypominam...

 
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "dodawanie_wezla.h"
#include "alebania.cpp"
#include "BigIntegerLibrary.h"
#include "interpolacja.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;

BigInteger Potega(BigInteger x, BigInteger y)
{
	BigInteger wynik=1;
	if (y!=0) for(BigInteger i=0;i<y;i=i+1) wynik=wynik*x;

	return(wynik);
}
BigInteger liczNWD (BigInteger a, BigInteger b)
{
	BigInteger c;
	while (b != 0)
	{
		c = a % b;
		a = b;
		b = c;
	}
	return(a);
}

void zwykly(bool a)
{
	Form2->Edit1->Visible=a;Form2->Label1->Visible=a;
	Form2->Edit2->Visible=a;Form2->Label2->Visible=a;
	Form2->Edit3->Visible=a;Form2->Label3->Visible=a;
	Form2->Edit4->Visible=a;Form2->Label4->Visible=a;
}

void dziesietny (bool a)
{
	Form2->Edit5->Visible=a;Form2->Label5->Visible=a;
	Form2->Edit6->Visible=a;Form2->Label6->Visible=a;
}

void doGrida(void)
{
	if ( (Form1->StringGrid1->ColCount==2) && (Form1->StringGrid1->Cells[1][0]=="") ) {}
	else Form1->StringGrid1->ColCount=Form1->StringGrid1->ColCount+1;

	int width=Form2->Test1->Width;
	if (Form2->Test2->Width > width) width=Form2->Test2->Width;
	if (Form2->Test3->Width > width) width=Form2->Test3->Width;
	if (Form2->Test4->Width > width) width=Form2->Test4->Width;

	Form1->StringGrid1->Cells[Form1->StringGrid1->ColCount - 1][0] = Form2->Test1->Caption;
	Form1->StringGrid1->Cells[Form1->StringGrid1->ColCount - 1][1] = Form2->Test2->Caption;
	Form1->StringGrid1->Cells[Form1->StringGrid1->ColCount - 1][2] = Form2->Test3->Caption;
	Form1->StringGrid1->Cells[Form1->StringGrid1->ColCount - 1][3] = Form2->Test4->Caption;
	Form1->StringGrid1->ColWidths[Form1->StringGrid1->ColCount - 1] = width + 3;
}

//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm2::FormShow(TObject *Sender)
{
	Form2->Edit1->Text="";Form2->Edit2->Text="";
	Form2->Edit3->Text="";Form2->Edit4->Text="";
	Form2->Edit5->Text="";Form2->Edit6->Text="";
	if (Form2->RadioButton2->Checked==true)
	{
		dziesietny(true);
		zwykly(false);
	}
	else
	{
		dziesietny(false);
		zwykly(true);
	}
}
//---------------------------------------------------------------------------
void __fastcall TForm2::RadioButton2Click(TObject *Sender)
{
		dziesietny(true);
		zwykly(false);
}
//---------------------------------------------------------------------------
void __fastcall TForm2::RadioButton1Click(TObject *Sender)
{
		dziesietny(false);
		zwykly(true);
}
//---------------------------------------------------------------------------
void __fastcall TForm2::DodajClick(TObject *Sender)
{

        DecimalSeparator = '.';
        Application->UpdateFormatSettings = false ;

	if (Form2->RadioButton2->Checked==true)
	{
		if ( (Form2->Edit5->Text=="") || (Form2->Edit6->Text=="") )
		{
			ShowMessage("Nie wszystkie pola zostały wypełnione.");

		}
		else
		{
			try
			{
				double a,b;
				a=StrToFloat(Edit5->Text);
				b=StrToFloat(Edit6->Text);

				if (Edit5->Text.Pos(".") == 0)
				{
					Test1->Caption=Edit5->Text;
					Test2->Caption=1;
				}
				else
				{
					BigInteger y;
					y=Potega(10, Form2->Edit5->Text.Length() - Form2->Edit5->Text.Pos("."));
					std::string s1=bigIntegerToString(y);
					Test2->Caption=s1.c_str();
					Test1->Caption=StringReplace(Edit5->Text,".","",TReplaceFlags());
				}

				if (Edit6->Text.Pos(".") == 0)
				{
					Test3->Caption=Edit6->Text;
					Test4->Caption=1;
				}
				else
				{
					BigInteger y;
					y=Potega(10, Form2->Edit6->Text.Length() - Form2->Edit6->Text.Pos("."));
					std::string s1=bigIntegerToString(y);
					Test4->Caption=s1.c_str();
					Test3->Caption=StringReplace(Edit6->Text,".","",TReplaceFlags());
				}

				BigInteger a1,b1,c1,d1,NWD;
				AnsiString help;
				std::string s2;

				help = Test1->Caption;
				s2 = help.c_str();
				a1=stringToBigInteger(s2);

				help = Test2->Caption;
				s2 = help.c_str();
				b1=stringToBigInteger(s2);

				help = Test3->Caption;
				s2 = help.c_str();
				c1=stringToBigInteger(s2);

				help = Test4->Caption;
				s2 = help.c_str();
				d1=stringToBigInteger(s2);

				NWD=liczNWD(a1,b1);
				a1=a1/NWD;b1=b1/NWD;
				NWD=liczNWD(c1,d1);
				c1=c1/NWD;d1=d1/NWD;

				s2=bigIntegerToString(a1);
				Test1->Caption=s2.c_str();
				s2=bigIntegerToString(b1);
				Test2->Caption=s2.c_str();
				s2=bigIntegerToString(c1);
				Test3->Caption=s2.c_str();
				s2=bigIntegerToString(d1);
				Test4->Caption=s2.c_str();

				doGrida();

				Form2->Edit1->Text="";Form2->Edit2->Text="";
				Form2->Edit3->Text="";Form2->Edit4->Text="";
				Form2->Edit5->Text="";Form2->Edit6->Text="";

			}
			catch(...)
			{
				ShowMessage("Nie wszystkie pola zostały wypełnione poprawnie.");
            }
		}
	}
	else
	{
		if ( (Form2->Edit1->Text=="") || (Form2->Edit2->Text=="") || (Form2->Edit3->Text=="") || (Form2->Edit4->Text=="") )
		{
			ShowMessage("Nie wszystkie pola zostały wypełnione.");

		}
		else
		{
			try
			{
				BigInteger a1,b1,c1,d1,NWD;
				AnsiString help;
				std::string s2;

				help = Edit1->Text;
				s2 = help.c_str();
				a1=stringToBigInteger(s2);

				help = Edit2->Text;
				s2 = help.c_str();
				b1=stringToBigInteger(s2);

				help = Edit3->Text;
				s2 = help.c_str();
				c1=stringToBigInteger(s2);

				help = Edit4->Text;
				s2 = help.c_str();
				d1=stringToBigInteger(s2);

				NWD=liczNWD(a1,b1);
				a1=a1/NWD;b1=b1/NWD;
				NWD=liczNWD(c1,d1);
				c1=c1/NWD;d1=d1/NWD;

				s2=bigIntegerToString(a1);
				Test1->Caption=s2.c_str();
				s2=bigIntegerToString(b1);
				Test2->Caption=s2.c_str();
				s2=bigIntegerToString(c1);
				Test3->Caption=s2.c_str();
				s2=bigIntegerToString(d1);
				Test4->Caption=s2.c_str();

				doGrida();

				Form2->Edit1->Text="";Form2->Edit2->Text="";
				Form2->Edit3->Text="";Form2->Edit4->Text="";
				Form2->Edit5->Text="";Form2->Edit6->Text="";

			}
			catch(...)
			{
				ShowMessage("Nie wszystkie pola zostały wypełnione poprawnie.");
			}
		}
	}



}
//---------------------------------------------------------------------------
0

Hym .Powiem tak , nie wiem co to ma robić , ale na pierwszy rzut oka (i na drugi też) to ten kod nie nadaje się do niczego .
1.Napisz co chcesz uzyskać w tym programie , co to robi ?
2.Jaki chcesz w końcu separator '.' czy ',' .Mozna zablokować wpisywanie nieodpowiedniego już na etapie wprowadzania danych
zamiast parsować String i odwalać jakieś kombinacje ,bo nikt normalny nie będzie się grzebał w tym bałaganie .
3.Ustalenie separatora dla aplikacji - **wystarczy to zrobić jeden raz ** np. jeśli chcesz aby był to znak '.' to :

 void __fastcall TFormX::FormCreate(TObject *Sender)  // OnCreate TForm
{
        DecimalSeparator = '.';
        Application->UpdateFormatSettings = false ;

} 

4.Ta konstrukcja nie jest poprawna :

if ( (Form2->Edit1->Text=="") || (Form2->Edit2->Text=="") ||.....

należy zawsze uzywać :

Form2->Edit1->Text.Trim() =="" ;

bo np. pozostawienie w edit spacji która nie jest widoczna , może powodować błędy w programie i wejście kodu w warunek który
nie powinien być spełniony .

0

Do niczego? Dlaczego? Może nie jest zbyt estetyczny i optymalny, ale działa jak chce, problem w tym, że tylko mnie na kompie...:(
Ad.1 Jest to program dokonujący interpolacji Lagrange'a, ale nie za pommocą liczb zmiennoprzecinkowych, tylko za pomocą liczb ułamkowych, w których licznik i mianownik jest reprezentowaany przez typ BigIntrger. Procedura wklejona przeze mnie ma za zadanie sprawdzić czy do Edit5 i Edit6 wprowadzono liczby zmiennoprzecinkowe, jeśli nie, to rzuci wyjątek. Mam 4 zmienne BigInteger. Oba Edity konwertuję i zapisuję za pomocą licznika i mianownika. Problem tak jakby leżał w funkcji FloatToStr...
Ad.2 No chcę kropkę. Nie wiem, czy jest sens coś blokować, bo na kompie bez RAD studio rzuca exception bez wzlędu na to, czy wpiszę '.', czy ','.
Ad.3 Do Form1 dla zdarzenia oncreate już próbowałem - efekt ten sam.
Ad.4 Nie wiedziałem. Dostosowałem się i nie bardzo pomogło.

0

**Debugera **użyj .Sprawdz co trafia do StrToFloat i co dalej się z tym dalej dzieje .
Po mojemu błąd jest w innym miejscu i dotyczy dalszej części kodu .
Może z operacjami na String jest coś nie w porządku.
String z VCL jest indeksowany od 1 nie od 0 .
Odwołanie się do elementu 0 powoduje wyjątek .

0

W dalszej części kodu raczej nie, bo zaraz po FloatToStr próbowałem sobie ustawić ShowMessage("UDAŁO SIĘ!!!"); i u mnie na kompie mam tego dialoga, a na tym bez RAD SUDIO dialoga z excepiona.
A gdzie ja się tam odwołuję do 0-wego elementu?
Edit5->Text.Pos(".") == 0 - o to chodzi? T Funkcja zwraca 0 jeśli "." nie znajdzie w stringu.
A co do debugera to spróbuję.

0

Nie wiem czy się odwołujesz.Nie mam całego kodu powiązanego z nagłówkami które tam masz .
Jeśli sytuacja występuje tylko po przeniesieniu aplikacji na inny komputer być może masz
źle ustawione opcje projektu aplikacji i wymagane są do jej działania jakieś komponenty
których na komputerze bez BCB nie ma .

http://math.uni.lodz.pl/~marekbad/files/grafika/kompilowanie.htm

I jeszcze na zakładce Compiler -> Release .

Tylko jeśli sprawdzasz program dajesz Full debug , do dystrybucji ->Release , bo mogą być różne jaja na innych komputerach .

0

Opcje standardowe, tylko link with dinamic RLT i build with rountime packages zmieniałem, żebi binarka była przenośna...

0

Zawsze mam Release - nawet w trakcie pisania

0

To źle , w czasie pisania i kompilacji w trybie Debug jeśli jest gdzieś błąd często dostajesz od razu breakpoint
ze wskazaniem miejsca w kodzie gdzie się prawdopodobnie znajduje .
Debuger to PODSTAWA .
Przy jego pomocy można się wiele nauczyć .
Np. czytelnego pisania kodu , instrukcja na linijkę żeby mu się dobrze pracowało :-)

0

No tak czy siak w trybie debug ten sam błąd... Kompiluje się, ale działa tylko u mnie.

0

Tak czy siak, włącz sobie człowieku myślenie bo bez tego daleko nie zajdziesz .
Do dystrybucji dajesz program w Release .
W trakcie pisania Debug , zakładasz pułapkę na miejscu gdzie podejrzewasz że jest błąd .
Jeśli u ciebie wszystko śmiga , budujesz program w trybie Release i wrzucasz na inny komputer .
Jeśli nie działa :
1.Wrzucasz najprostszy program , sam formularz w Release na inny komputer .
2.Jeśli działa wrzucasz program z samą funkcją StrToFloat i jakimś oknem które pozwala na ocenę jej działania .
3.Jeśli działa dołączasz resztę kodu .
4.Jeśli w którymś z 3 przypadków występuje błąd masz przynajmniej określony etap na którym należy go poszukiwać .
Powodzenia .

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