Funktion, die ein Struct-Array zurückgibt -> wie?



  • Ich möchte gern aus einer Funktion ein Struct-Array zurückgeben, nur leider habe ich das bis jetzt nicht so hinbekommen, wie ich das möchte.

    Ein (vereinfachtes) Beispiel zur Erläuterung:

    //Meine Struktur
    struct daten
    {
      int id;
      AnsiString name; //<-- AnsiString könnte ein Problem sein,
                             soll aber so bleiben
    }
    
    //Meine Funktion (eine richtige Rückgabe wäre auch nicht schlecht)
    void funktion(struct daten *liste)
    {
      liste[0].id = 2;
      liste[0].name = "Person1";
      liste[1].id = 5;
      liste[1].name = "Person2";
    //...
    }
    
    void main()
    {
      struct daten alle[100];
      funktion(&alle[0]);
      //Weiterverarbeitung von daten
    }
    

    Das Beispiel müsste zwar ohne Laufzeitfehler starten, name bleibt aber leer.
    Außerdem habe ich das Problem, das ich in der Funktion nicht ermitteln kann, wie viel Array-Elemente übergeben werden.

    Also wenn jemand eine Idee hat, wie man sowas macht, bitte melden!
    Bitte keine Lösung mit Klassen und Objekten. Und wenn es komplett falsch ist oder gar nicht geht, bitte ein Auge zudrücken und verbessern.

    Also danke schonmal!

    MfG

    Knowman



  • Knowman schrieb:

    Bitte keine Lösung mit Klassen und Objekten.

    Dann sieh mal zu, dass du den AnsiString loswirst, das ist nämlich eine Klasse. 😉

    Ansonsten scheint der Code doch zu funktionieren, vom fehlenden Semikolon am struct mal abgesehen. Ich hatte jedenfalls kein Problem, alle[0].name auszulesen.



  • Bitte poste mal den kompletten Code !

    Was z.B. ist:

    liste[0].id = 2; 
      liste[0].name = "Person1"; 
      liste[1].id = 5; 
      liste[1].name = "Person2";
    

    Liste wurde in diesem Code doch nicht deklariert!



  • *void funktion(struct daten liste)

    😉



  • Ja, Ihr habt recht, deshalb poste ich hier mal den Code (Ausschnitte aus einem Programm in C++ Builder), das Programm wandelt im großen und ganzen Structs in Zeichenketten in einem bestimmten Syntax um und auch wieder zurück.

    //Struct für Waren
    struct struct_waren
    {
      int id;
      AnsiString name;
      float preis;
    };
    
    //Struct -> String
    AnsiString struct_waren2string(struct struct_waren liste[])
    {
      AnsiString as_ret = ""; //Zwischenspeicher für AnsiString-Rückgabewert
      int liste_index = 0;
    
      while(liste[liste_index].name != "")
      {
        /* ... Struct -> String; speichern in as_ret ... */
    
        liste_index++;
      }
    
      return as_ret;
    }
    
    //String -> Struct
    void string2struct_waren(struct struct_waren *liste, AnsiString structasstring)
    {
      AnsiString as_zw1, as_zw2, as_feldname, as_feldwert; //Zwischenspeicher für AnsiString
      int liste_index = 0; //Momentaner Index im Struct-Array mit Datensätzen
      int pos_start, pos_length; //Paramenterspeicher für SubString()-Funktion
    
    /* ... String aufsplitten ... */
    
          //Daten in Struct-Array übertragen
          if( as_feldname == "id" ) liste[liste_index].id = as_feldwert.ToInt();
          if( as_feldname == "name" ) liste[liste_index].name = as_feldwert;
          if( as_feldname == "preis" ) liste[liste_index].preis = as_feldwert.ToDouble();  //leider kein ToFloat
    }
    
    //Listboxen -> Struct -> String
    void __fastcall TForm1::b_2stringClick(TObject *Sender)
    {
      struct struct_waren waren[100];
    
      for(int waren_index = 0; waren_index < lb_id->Items->Count; waren_index++)
      {
        waren[waren_index].id = lb_id->Items->Strings[waren_index].ToInt();
        waren[waren_index].name = lb_name->Items->Strings[waren_index];
        waren[waren_index].preis = lb_preis->Items->Strings[waren_index].ToDouble();
      }
    
      re_2string->Text = struct_waren2string(waren);
    }
    
    //String -> Struct -> Listboxen
    void __fastcall TForm1::b_2structClick(TObject *Sender)
    {
      struct struct_waren waren[100];
      string2struct_waren(&waren[0], re_2string->Text);  // <- Mein Problem
    
      lb_id->Items->Clear();
      lb_name->Items->Clear();
      lb_preis->Items->Clear();
    
      int waren_index = 0;
      while(waren[waren_index].name != "" && waren_index < 100)
      {
        lb_id->Items->Add(waren[waren_index].id);
        lb_name->Items->Add(waren[waren_index].name);
        lb_preis->Items->Add(waren[waren_index].preis);
    
        waren_index++;
      }
    }
    

    So, das ist eigentlich mehr Code als nötig, aber vielleicht liegt das Problem ja im Zusammenhang.

    Edit: Das eigentliche Problem hat sich erledigt, siehe unten.



  • Ich habe meinen Fehler gefunden!

    Es funktioniert also doch (muss ja). Ich weiß nur nicht, ob es vielleicht eleganzer geht (die Übergabe vielleicht ohne Zeiger und Referenzen?)

    Außerdem, wie kann ich einen String in eine Float-Zahl umwandeln?

    Danke schonmal!

    Knowman



  • FloatToStr konvertiert eine Gleitkommazahl in den entsprechenden AnsiString-Wert.
    <restl. Fullquote aus der Hilfe gelöscht>

    Edit:
    Zitate bitte auf das Notwendigste beschränken. Danke!



  • <Fullquote gelöscht>

    OK, Danke schön.

    Und gibt es eine Möglichkeit festzustellen, wieviel wie groß das übergebene Struct-Array ist (wieviel Elemente)? Mit sizeof() funktioniert das ja wegen dem AnsiString nicht.

    2. Und gibt es auch eine Lösungsvariante, bei der man so ein Struct-Array auch richtig zurückgeben lassen könnte. Dann könnte ich die Funktion (mit overloading) für mehrere Structs ausbauen.

    Edit:
    Zitate bitte auf das Notwendigste beschränken. Danke!



  • Wofür bedankst du dich?
    Da hast gefragt, wie man String in Float wandelt, und Ag3nt, in seinem scheinbar zwanghaften Konversationstrieb, erklärt dir, wie man Float in String umwandelt!?

    Ganz davon abgesehen, dass du in deinem Code bereits ToDouble verwendest, die Frage also eigentlich hinfällig ist.

    Oder habe ich irgendwas verpasst?

    Was die Arrayelemente angeht, selbstverständlich kann man die Anzahl mittels sizeof() ermitteln. Ausgehend von deinem ersten beispielcode:

    struct daten alle[100];
    Caption = sizeof(alle) / sizeof(daten);
    


  • Ich kenne sizeof(), nur leider sind die Werte nicht brauchbar, da ich in meinem Struct einen AnsiString verwende.

    sizeof(alle)
    

    liefert immer das gleiche Ergebnis (4), egal wieviel Elemente im Array sind.



  • In deinem ursprünglichen Beispiel, auf das ich mich beziehe, wird ja wohl auch AnsiString als Element verwendet. Und das o.g. sizeof/sizeof-Beispiel funktioniert damit einwandfrei. Nochmal der Vollständigkeit halber den getesteten Code:

    struct daten
    {
      int id;
      AnsiString name;
    };
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
      struct daten alle[100];
      int A = sizeof(alle);   // A = 800
      int B = sizeof(daten);  // B = 8
      Caption =  A / B;       // Ergebnis = 100
    }
    


  • Stimmt, das funktioniert, wenn ich sizeof() direkt aufrufe.
    Ich gesagt, dass es nicht geht, weil es auf eine Referent angewendet nicht so funktioniert. Ich kann die Größe des an die Funktion via Referenz übergebenen Arrays nicht über diese Referenz auslesen.
    Da muss ich wohl einen anderen Lösungsansatz benutzen.


Log in to reply