Fehler bei struct Klasse



  • Hallo Zusammen,
    ich habe zur Übung mal einen Einheitenumrechner gebastelt und wollte es etwas eleganter lösen mit einer struct Klasse.
    Am anfang hat es super funktioniert, ich habe nun noch eine Variable hinzugefügt und jetzt bekomme ich fehlermeldungen und er bringt die Datensätze durcheinander. Hat jemand eine Idee was ich falsch mache?

    Gruß Ska

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit11.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm11 *Form11;
    const int L=10,D=4,T=2,Ma=9;
    struct CEinheiten
    {
    String Einheit;
    double Faktor;
    }Laenge[L],Druck[D],Masse[Ma],Temperatur[T],Test
    ;
    //CEinheiten Laenge[L], Druck[D],  Temperatur[T], Masse[Ma],Dummy[3];
    char Auswahl;
    
    //---------------------------------------------------------------------------
    __fastcall TForm11::TForm11(TComponent* Owner)
    	: TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    
    //---------------------------------------------------------------------------
    double EUR (double x1,double x2)
    {
    	double z,y;
    	z=x1/x2;
    	y= (StrToFloat(Form11->Edit1->Text)) * z;
    	return y;
    }
    //---------------------------------------------------------------------------
    double EURT (int x1,int x2)
    {
    double y;
    
    if ((x1==0) && (x2==1))     y = (((StrToFloat(Form11->Edit1->Text)) * 9)/5)+32;
    if ((x1==0) && (x2==2))     y = StrToFloat(Form11->Edit1->Text) + 273.15;
    if ((x1==1) && (x2==0))     y = (((StrToFloat(Form11->Edit1->Text))-32) * 5)/9;
    if ((x1==1) && (x2==2))     y = ((((StrToFloat(Form11->Edit1->Text))-32) * 5)/9)+273.15;
    if ((x1==2) && (x2==0))     y = StrToFloat(Form11->Edit1->Text) - 273.15;
    if ((x1==2) && (x2==1))     y = ((((StrToFloat(Form11->Edit1->Text))-273.15) * 9)/5)+32;
    if (x1==x2) y = StrToFloat(Form11->Edit1->Text);
    
    
    return y;
    
    }
    
    
    
    //---------------------------------------------------------------------------
    void Init(void)
    {
    	Form11->ComboBox1->Items->Add ("Länge");
    	Laenge[0].Einheit =   "Meter";
    	Laenge[0].Faktor = 1;
    	Laenge[1].Einheit =   "Kilometer";
    	Laenge[1].Faktor = 1000;
    	Laenge[2].Einheit =   "Millimeter";
    	Laenge[2].Faktor = 0.001;
    	Laenge[3].Einheit =   "Zentimeter";
    	Laenge[3].Faktor = 0.01;
    	Laenge[4].Einheit =   "Micrometer";
    	Laenge[4].Faktor = 0.000001;
    	Laenge[5].Einheit =   "Nanometer";
    	Laenge[5].Faktor = 0.000000001;
    	Laenge[6].Einheit =   "Zoll";
    	Laenge[6].Faktor = 0.02539998628400740663600041655978;
    	Laenge[7].Einheit =   "Meile";
    	Laenge[7].Faktor = 1609;
    	Laenge[8].Einheit =   "Fuß";
    	Laenge[8].Faktor = 0.30479999024640031211519001231392;
    	Laenge[9].Einheit =   "Yard";
    	Laenge[9].Faktor = 0.91440275783871764157240698237946;
    	Laenge[10].Einheit =   "Seemeile";
    	Laenge[10].Faktor = 1852;
    
    	Form11->ComboBox1->Items->Add ("Druck");
    	Druck[0].Einheit =   "Bar";
    	Druck[0].Faktor = 1;
    	Druck[1].Einheit =   "Pascal";
    	Druck[1].Faktor = 0.00001;
    	Druck[2].Einheit =   "Physikalische Atmosphäre";
    	Druck[2].Faktor = 1.013;
    	Druck[3].Einheit =   "Pund-force per square inch";
    	Druck[3].Faktor = 0.06894744825494008466746645706642;
    	Druck[4].Einheit =   "Torr";
    	Druck[4].Faktor = 0.00133322312022206164290418658724;
    
    	Form11->ComboBox1->Items->Add ("Temperatur");
    	Temperatur[0].Einheit =   "Grad Celsius";
    	Temperatur[0].Faktor = 1;
    	Temperatur[1].Einheit =   "Grad Fahrenheit";
    	Temperatur[1].Faktor = 1;
    	Temperatur[2].Einheit =   "Kelvin";
    	Temperatur[2].Faktor = 1;
    
    	Form11->ComboBox1->Items->Add ("Masse");
    	Masse[0].Einheit =   "Tonne";
    	Masse[0].Faktor = 1000000;
    	Masse[1].Einheit =   "Kilogramm";
    	Masse[1].Faktor = 1000;
    	Masse[2].Einheit =   "Gramm";
    	Masse[2].Faktor = 1;
    	Masse[3].Einheit =   "Milligramm";
    	Masse[3].Faktor = 0.001;
    	Masse[4].Einheit =   "Microgramm";
    	Masse[4].Faktor = 0.000001;
    	Masse[5].Einheit =   "Long ton";
    	Masse[5].Faktor = 1016000;
    	Masse[6].Einheit =   "Short ton";
    	Masse[6].Faktor = 907200;
    	Masse[7].Einheit =   "Stone";
    	Masse[7].Faktor = 6350;
    	Masse[8].Einheit =   "Pfund";
    	Masse[8].Faktor = 453.6;
    	Masse[9].Einheit = "Unze";
        Masse[9].Faktor = 28.35;
    
    }
    //---------------------------------------------------------------------------
    void Zuweisung (void)
    {
    	Form11->ComboBox2->Items->Clear();
    	Form11->ComboBox3->Items->Clear();
    	if (Form11->ComboBox1->Text == "Länge")
    	{
    	   for (int i=0; i<=L; i++)
    	   {
    			Form11->ComboBox2->Items->Add (Laenge[i].Einheit);
    			Form11->ComboBox3->Items->Add (Laenge[i].Einheit);
    
    	   }
    	   Auswahl = 'L';
    	}
    	if (Form11->ComboBox1->Text == "Druck")
    	{
    		for (int i=0; i<=D; i++)
    		{
    			Form11->ComboBox2->Items->Add (Druck[i].Einheit);
    			Form11->ComboBox3->Items->Add (Druck[i].Einheit);
    
    		}
    			Auswahl = 'D';
    	}
    	if (Form11->ComboBox1->Text == "Temperatur")
    	{
    		for (int i=0; i<=T; i++)
    		{
    			Form11->ComboBox2->Items->Add (Temperatur[i].Einheit);
    			Form11->ComboBox3->Items->Add (Temperatur[i].Einheit);
    
    		}
    			Auswahl = 'T';
    	}
    	if (Form11->ComboBox1->Text == "Masse")
    	{
    		for (int i=0; i<=Ma; i++)
    		{
    			Form11->ComboBox2->Items->Add (Masse[i].Einheit);
    			Form11->ComboBox3->Items->Add (Masse[i].Einheit);
    
    		}
    			Auswahl = 'M';
    	}
    	Form11->ComboBox2->ItemIndex = 0;
    	Form11->ComboBox3->ItemIndex = 1;
    }
    //---------------------------------------------------------------------------
    void Rechnen (void)
    {
    	switch (Auswahl)
    	{
    	case 'L':
    	Form11->Edit2->Text = FloatToStr (EUR (Laenge[Form11->ComboBox2->ItemIndex].Faktor, Laenge[Form11->ComboBox3->ItemIndex].Faktor));
    	break;
    	case 'D':
    	Form11->Edit2->Text = FloatToStr (EUR (Druck[Form11->ComboBox2->ItemIndex].Faktor, Druck[Form11->ComboBox3->ItemIndex].Faktor));
    	break;
    	case 'T':
    	Form11->Edit2->Text = FloatToStr (EURT (Form11->ComboBox2->ItemIndex, Form11->ComboBox3->ItemIndex));
    	break;
    	case 'M':
    	Form11->Edit2->Text = FloatToStr (EUR (Masse[Form11->ComboBox2->ItemIndex].Faktor, Masse[Form11->ComboBox3->ItemIndex].Faktor));
        break;
    	}
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm11::ComboBox1Change(TObject *Sender)
    {
      	Zuweisung();
    	Rechnen();
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm11::FormCreate(TObject *Sender)
    {
    	Init();
    	Zuweisung();
    	Rechnen();
    
    
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm11::ComboBox2Change(TObject *Sender)
    {
    	Rechnen();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm11::ComboBox3Change(TObject *Sender)
    {
    	Rechnen();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm11::Edit1Change(TObject *Sender)
    {
    	Rechnen();
    }
    //---------------------------------------------------------------------------
    


  • Bitte packe deinen Code in Code-Tags (du kannst deinen Beitrag auch nachträglich noch "Bearbeiten" - über das 3-Punkte Menü).
    Und es reicht ersteinmal, den relevanten Code zu posten.

    und jetzt bekomme ich fehlermeldungen

    Diese solltest du uns auch mitteilen...

    Und die Überschrift ist auch nichtssagend.



  • @Skator123 sagte in struct Klasse:

    const int L=10,D=4,T=2,Ma=9;
    struct CEinheiten
    {
    String Einheit;
    double Faktor;
    }Laenge[L]

    Also, der gesamte Code ist sehr verwirrend, aber ich vermute einfach mal:
    dein L ist 10. Du hast also 10 Elemente von Länge. Du greifst aber auf Laenge[10] zu. Das wäre aber schon das 11. Element. Auch bei den anderen Größen passt deine Länge nicht. Druck soll 4 Elemente haben, aber die Indizes 0,1,2,3,4 sind 5 Elemente, auf die du zugreifst.

    Genereller Rat: mische nicht Programmlogik mit irgendwelchem Anzeigekrempel. Und nicht alle Einheiten kann man einfach mit einem Faktor umrechnen.

    Und: bitte auf bearbeiten gehen, gesamten Code markieren und den </>-Button drücken! Edit: danke 👍



  • @wob Danke für den Hinweis ich habe den Fehler gefunden. Ich habe gedacht, dass der Indizi vom Datenfeld auch bei 0 anfängt... Ja es lassen sich nicht alle mit einem Faktor umrechnen aber die meisten und das klappt ganz gut. Für die Ausnahmen habe ich eine extra Berechnung.

    Und Sorry für die unformatierte Anzeige... ich lerne ja noch dazu 🙂

    Gruß Ska



  • @Skator123 sagte in Fehler bei struct Klasse:

    Ich habe gedacht, dass der Indizi vom Datenfeld auch bei 0 anfängt... J

    Fängt es auch.

    Aber bei der Definition vom Array wird die Anzahl der Elemente angegeben (und nicht der maximale Index)



  • Und noch ein wichtiger Rat beim Umgang mit der VCL:
    Benutze niemals die globalen Form-Variablen, d.h. bei dir z.B. Form11.
    Erzeuge deine (bisher freien) Funktionen als Memberfunktionen der Form-Klasse, so daß du direkt auf die Controls zugreifen kannst (oder wenn schon, dann übergebe diese als Zeiger [als zusätzlichen Parameter], so daß du einfach this beim Aufruf übergibst).

    Empfehlenswert auch (wenn auch in englisch - und schon etwas älter): Programming in C++Builder | Better Programming Practices in C++Builder .



  • Ja so meinte ich das... hab die Definition vom Array um eins erhöht...



  • @Th69 Danke für den Hinweis



  • Ich glaube, der Hinweis von @Th69 ist etwas kurz geraten. Deine Funktionen EUR und EURT sollten nicht Member der Klasse sein, sondern frei bleiben. Viel mehr würde ich mir Gedanken machen, was eigentlich genau die Aufgabe dieser Funktionen ist. Füge JEDER Funktion einen kurzen Kommentar hinzu, was diese Funktion tut, was ihre Input-Parameter sind und was sie zurückgibt. Wenn das schwer ist, weil die Beschreibung kompliziert wäre, dann ist die Funktion nicht gut. Warum hängen diese beiden Funktionen von Form1 ab? Das ist schlecht, wie Th69 schon schrieb. Hier wäre es aber keine sinnvolle Lösung, die Funktion einfach als Member zu verwenden. Vielmehr sollte sie wohl noch einen dritten Parameter, nämlich den Float, den du aus dem Form1->Edit1 holst, bekommen.

    Und wo ich gleich dabei bin: deine Funktion EURT - was tut die? Was bedeuten all die x1 und x2-Werte? Wer soll das verstehen/lesen? Viel klarer wären Funktionen celsius_to_fahrenheit und fahrenheit_to_celsius, vielleicht auch noch je 2 Fkt zur Konvertierung in Kelvin. Dann sieht man am Namen direkt, was die Funktion tut. Diese braucht dann nur einen float als Parameter zu bekommen. Und selbstverständlich darf sie nicht von Form1 (oder irgendeiner anderen Form) abhängen, denn die Umrechnung hat überhaupt nichts mit deinen Forms zu tun. Im OnChange/OnClick oder anderen Events der Form kannst du dann die Konvertierungsfunktion aufrufen.


Anmelden zum Antworten