Announcement

Collapse
No announcement yet.

Zeiger/Array und Dateiverwaltung

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Zeiger/Array und Dateiverwaltung

    Moin moin,

    ich habe nen Problem bei der Übergabe eines Arrays an eine Funktion.
    Der Code dazu schaut zur Zeit so aus:
    (Klassen vom CBuilder hab ich aus dem Code der Übersichtlichkeit wegen entfernt)

    Control.h
    Code:
    struct DataStruct{
        int Nummer;
        char Name[20];
    };
    int LoadData(char PPath[100], struct DataStruct Cache[]);
    Control.cpp
    Code:
    #include "Control.h"
    #include <fstream>
    #include <iostream>
    using namespace std;
    int LoadData(char PPath[100], struct DataStruct Cache[]){
        ifstream DATA;
        int A = 0;
        DATA.open(PPath, ios::in | ios::binary );
        if(DATA){
            while( !DATA.eof() ){
                FILE.read((char*)&Cache[A], sizeof(Cache[A]) );
                if(!DATA.eof()){
                    A++;
                }
            }
        }
        DATA.close();
        return A;
    }
    Hauptdatei.cpp
    Code:
    #include "Control.h"
    int Var1= 1;
    AnsiString DataPath = "Datacontrol.dat"
    DataStruct Arrays[300];
    
    int main(){
      Var1 = LoadData( DataPath.c_str(), Arrays );
      for(int H = 0; H < Var1; H++){
        Memo1->Lines->Add( Arrays[H].Name );
      }
      return 0;
    }
    Meine Fragen bezüglich des Codes sind nun:
    Wurde das Struct Array richtig an die Funktion LoadData übergeben?
    - sprich: Besitzt die Funktion die Adressen von dem originalen Struct-Objekt und schreibt auch in dieses Objekt ?

    Muss ich in der Funktion LoadData den Pointer auf deraStruct noch irgendwie NULLen und entfernen?

    Muss ich das anlegen des Objekts von dem Struct in der Hauptdatei.cpp vornehmen oder kann ich das gleich in die Control.h hineinschrieben, damit allen ein globales Objekt des Structs verwenden?
    - wenn ich das jedoch mache, sagt mir der Compiler, dass die Objekte Arrays zwei Mal erzeugt werden, was ich nicht verstehe

    Greez Pixtar

  • #2
    Mir ist ein völliges Rätsel, warum du nun die Vorteile des C++Builders nicht nutzt und mit chars und fstream arbeitest.

    Zu deiner Frage:

    Siehe hier
    http://www.marquardtnet.info/cecke/q...quicky_15.html

    Insbesondere, da du ja den Weg wählst -> Pkt 2.
    Christian

    Comment


    • #3
      Danke für den Link, jedoch ist es ein größeres Projekt und die Funktionen sind halt ausgelagert, da die Funktionen in mehreren Programmen verwendet werden.
      Aus diesem Grund habe ich das Struct nicht mit in die Klasse des BCB aufgenommen. ^^

      Achja und zu den chars .. wie soll ich sagen, das ständige Konvertieren ist blöd, vorallem bei der Benutzung von Binärdateien die feste Werte brauchen, was nen String halt net har ^^

      Comment


      • #4
        Ja, wenn man gezungen ist das zu nutzen ist das hin und her mehr als lästig
        Christian

        Comment


        • #5
          Originally posted by Pixtar View Post
          Wurde das Struct Array richtig an die Funktion LoadData übergeben?
          - sprich: Besitzt die Funktion die Adressen von dem originalen Struct-Objekt und schreibt auch in dieses Objekt ?
          Also: du hast die Function nicht getestet? Nach einen Test weist mann doch ob es functioniert?

          Muss ich in der Funktion LoadData den Pointer auf deraStruct noch irgendwie NULLen und entfernen?
          Ich weis nicht was du willst.

          Muss ich das anlegen des Objekts von dem Struct in der Hauptdatei.cpp vornehmen oder kann ich das gleich in die Control.h hineinschrieben, damit allen ein globales Objekt des Structs verwenden?
          - wenn ich das jedoch mache, sagt mir der Compiler, dass die Objekte Arrays zwei Mal erzeugt werden, was ich nicht verstehe
          Man darf niemals ein object erzeugen in ein .h oder .hpp file. Nur die definition eines Object gehört da. (Sonst erzeugt jeder .cpp file der diese .h file include so ein Object. Na dass hast du gemerkt!).


          In der .ccp file:
          DataStruct DataStructs[300] = {0};

          int der .h fille
          extern DataStruct DataStructs[];

          (Du nenst dass Arrays. Aber dan sieht mann nicht mehr den Typ).

          Ich würde auch nicht die fuction so typeren:

          int LoadData(char PPath[100], struct DataStruct Cache[]);

          Sondern:

          int LoadData(char *PPath, DataStruct *Cache );

          Comment


          • #6
            Danke Hans, dass du auf meine Fragen eingegangen bist,

            Also: du hast die Function nicht getestet? Nach einen Test weist mann doch ob es functioniert?
            Ja, getestet habe ich das alles und es macht auch das was es soll, nur will ich die Performance nicht herunter ziehen dadurch, das ich irgendwo tote Pointer rumliegne habe, die ich garnicht mehr benutze.

            Muss ich in der Funktion LoadData den Pointer auf deraStruct noch irgendwie NULLen und entfernen?
            Wo wir bei dem Thema wären Pointer. Wenn ich die Funktion so deklariere wie du vorgeschlagen hast, dann habe ich ja einen Pointer auf ein Objekt. Sollte ich den nach Ende der Funktion nicht mehr nutzen wollen, müsste ich doch folgendes schreiben:

            Cache = NULL
            delete Cache;

            Oder habe ich irgendwo im Kapitel Pointer doch nicht aufgepasst. ^^

            int der .h fille
            extern DataStruct DataStructs[];
            Was genau bewirkt diese Ziele?

            Sondern:
            int LoadData(char *PPath, DataStruct *Cache );
            Werde ich ausprobieren. ^^

            Comment


            • #7
              Originally posted by Pixtar View Post
              Wo wir bei dem Thema wären Pointer. Wenn ich die Funktion so deklariere wie du vorgeschlagen hast, dann habe ich ja einen Pointer auf ein Objekt. Sollte ich den nach Ende der Funktion nicht mehr nutzen wollen, müsste ich doch folgendes schreiben:

              Cache = NULL
              delete Cache;
              Die pointer ist nur ein parameter einer Function. Darüber kummert mann sich nicht. (Und weshalb allein uEber Cache und nich ueber PPath? Dass ist acht ein Pointer. (Beide sind nur 4 bytes auf den Stack)

              Zum zweiten benutzt mann delete oder delete[] nur auf objecte die mit new oder new[] gemacht sind. Dass ist hier auch nicht der fall. Aber die function hat eben die globale strucct mit daten gefuelt. Soll es jetzt die ganze struct deleten? (Die anrufende function wuerde dass nicht lieben)


              Was genau bewirkt diese Ziele?
              Genau das was du wilst: ..., damit allen ein globales Objekt des Structs verwenden; kunnen.

              Werde ich ausprobieren.
              Die Function selbst bleibt unveränderd.

              Comment


              • #8
                Verstehe ich nicht ganz .. wenn ich doch die Objekte von der "Hauptprogramm.cpp" der "Control.cpp" per "extern DataStruct DataStructs[]" zur Verfügung stelle, warum sollte ich der Funktion das Objekt noch per Parameter übergeben?

                Control.cpp
                Code:
                #include "Control.h"
                #include <fstream>
                #include <iostream>
                using namespace std;
                extern DataStruct DataStructs[];
                
                int LoadData(char PPath[100]){
                    ifstream DATA;
                    int A = 0;
                    DATA.open(PPath, ios::in | ios::binary );
                    if(DATA){
                        while( !DATA.eof() ){
                            FILE.read((char*)&DataStructs[A], sizeof(DataStructs[A]) );
                            if(!DATA.eof()){
                                A++;
                            }
                        }
                    }
                    DATA.close();
                    return A;
                }
                So funktioniert es aufjedenfall nicht ... *g*

                Comment


                • #9
                  Originally posted by Pixtar View Post
                  So funktioniert es aufjedenfall nicht ... *g*
                  So könnte es gut functionieren.

                  Was geht denn nicht?

                  Verstehe ich nicht ganz .. wenn ich doch die Objekte von der "Hauptprogramm.cpp" der "Control.cpp" per "extern DataStruct DataStructs[]" zur Verfügung stelle, warum sollte ich der Funktion das Objekt noch per Parameter übergeben?
                  Weil es keine gute weise von programmieren is om eine function wie LoadData() nur mit eine structur arbeiten zu lassen die dann auch noch in eine andere .cpp file definiiert is. Dann köntest du die PPath variabele auch weglassen. Du wilst doch aus verschiedene dateien verschiedene structuren laden können?

                  Wenn du in Hauptdatei.cpp zwei datasets declarierst:

                  DataStruct MyDataStructs[10];
                  DataStruct YourDataStructs[23];

                  AnsiString MyFileName = "mydatastructs.dat";
                  AnsiString YourFileName = "yourdatastructs.dat";

                  Dan kanst du die mit der selbe function laden

                  int nmystructs = LoadData ( MyFileName, MyDataStructs );
                  int nyourstructs = LoadData (YourFileName, YourDataStructs );

                  So weit.

                  Und dann noch: wie wäre es mit:

                  int nmystructs = LoadData ( MyFileName, MyDataStructs, 10 );
                  int nyourstructs = LoadData (YourFileName, YourDataStructs, 23 );


                  Und du arbeitest mit relatieve paths. Dass gibt auf die dauer immer erger. Weil die 'current directory' sich ändern kan. Also immer absolute pfade nutzen:

                  AnsiString MyFileName = ExtractFilePath(ParamStr(0)) + "mydatastructs.dat";
                  AnsiString YourFileName = ExtractFilePath(ParamStr(0)) + "yourdatastructs.dat";

                  Comment

                  Working...
                  X