Adresskarteikarten, C++ , Stream! Hilfe ^^



  • Hi @ all User,

    Habe da nen Problem:

    Fehler beim Laden, es werden nur leere Strings geladen, außer der Postleitzahl, die wird 0 !
    scheinbar werden die werte nicht übergeben!

    Speichern, es legt keine neue Datei an! Quasie sollte das meines erachtens werden wie einen Neuen Datensatz erzeugen, + Den Datensatzinhalteinfügen!

    Datensatzzählen, habe versucht ans ende zu springen und mit der tellg funktion wollte ich die größe erfahren (soll ja die gesamtgröße zurückgeben) und diese wollte ich dann durch den Datensatz selbst Teilen Quasie ganz simpel um den aktuellen Datensatz zu erfahren jedoch liefert tellg mir imme -1 zurück KP warum!

    Hier das Programm:
    Das Progie (Borland C++ Buielder 6)

    Und hier der QuellCode:

    Meine Header Datei

    #include <fstream.h>
    
            //Datensatzstruktur für Adresskartei definieren!
            struct pAdrDatensatz
            {
              char          Nachname[32];
              char          Vorname[17];
              char          Strasse[42];
              char          Nr[7];
              char          Ort[27];
              unsigned int  PLZ;
              char          Tel[22];
              char          email[32];
              char          Geburtsdatum[12];
            };
            //Datensatz
            pAdrDatensatz myDat;
    
            //Datei -speichern -laden
            AnsiString DateiName;
            //Stream
            ofstream dat_io;
            ifstream dat_in;
            //Datei offen ?
            bool Dat_Open;
    

    Konstruktor

    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
      //Datei offen == false (geschlossen)
      Dat_Open=false;
    
      //Verzeichnis der Anwendung ermitteln
      AnsiString Pfad=ExtractFileDir(Application->ExeName);
    
      //Standart verzeichnis festlegen für den open & save Dialog!
      SaveDialog1->InitialDir = Pfad;
      OpenDialog1->InitialDir = Pfad;
    
      //Einstellung der Größe von Form1 (Karteikarte)
      Form1->Width  = Panel1->Width + 18;
      Form1->Height = Panel1->Height + 15 + Button1->Height + 75;
    
      //Ermitteln der maximalen länge des Textes in den Edit Feldern
      E_Nachname->MaxLength         =sizeof(myDat.Nachname)-2;
      E_Vorname->MaxLength          =sizeof(myDat.Vorname)-2;
      E_Strasse->MaxLength          =sizeof(myDat.Strasse)-2;
      E_NR->MaxLength               =sizeof(myDat.Nr)-2;
      E_ORT->MaxLength              =sizeof(myDat.Ort)-2;
      E_TEL->MaxLength              =sizeof(myDat.Tel)-2;
      E_email->MaxLength            =sizeof(myDat.email)-2;
      E_Geburtsdatum->MaxLength     =sizeof(myDat.Geburtsdatum)-2;
    
      //Hint --> Angabe der Max. Breite der Felder
      E_Nachname->Hint="maximal"     + IntToStr(sizeof(myDat.Nachname)-2) + "Zeichen";
      E_Vorname->Hint="maximal"      + IntToStr(sizeof(myDat.Nachname)-2) + "Zeichen";
      E_Strasse->Hint="maximal"      + IntToStr(sizeof(myDat.Nachname)-2) + "Zeichen";
      E_NR->Hint="maximal"           + IntToStr(sizeof(myDat.Nachname)-2) + "Zeichen";
      E_ORT->Hint="maximal"          + IntToStr(sizeof(myDat.Nachname)-2) + "Zeichen";
      E_TEL->Hint="maximal"          + IntToStr(sizeof(myDat.Nachname)-2) + "Zeichen";
      E_email->Hint="maximal"        + IntToStr(sizeof(myDat.Nachname)-2) + "Zeichen";
      E_Geburtsdatum->Hint="maximal" + IntToStr(sizeof(myDat.Nachname)-2) + "Zeichen";
    }
    //---------------------------------------------------------------------------
    

    Dummy Button --> Testwerte

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
      //Dummy Werte übergeben in die Struktur! können nicht zugewiesen werden müssen kopiert werden
      strcpy(myDat.Nachname,     "Müller");
      strcpy(myDat.Vorname,      "Manfred");
      strcpy(myDat.Strasse,      "Am Höllenschlund");
      strcpy(myDat.Nr,           "666a");
      strcpy(myDat.Ort,          "Hölle");
      myDat.PLZ                  = 666;
      strcpy(myDat.Tel,          "Devil-666");
      strcpy(myDat.email,        "Hölle@666.com");
      strcpy(myDat.Geburtsdatum, "01.01.0001");
    
      //int n=sizeof (myDat);
      //Werte in die Edit Felder ausgeben
      E_email->Text         = myDat.email;
      E_Geburtsdatum->Text  = myDat.Geburtsdatum;
      E_Nachname->Text      = myDat.Nachname;
      E_Vorname->Text       = myDat.Vorname;
      E_NR->Text            = myDat.Nr;
      E_ORT->Text           = myDat.Ort;
      E_PLZ->Text           = IntToStr(myDat.PLZ);
      E_Strasse->Text       = myDat.Strasse;
      E_TEL->Text           = myDat.Tel;
    }
    //---------------------------------------------------------------------------
    

    Beenden

    void __fastcall TForm1::Beenden1Click(TObject *Sender)
    {
      Form1->Close();
    
      if (Dat_Open == true)
      {
        dat_io.close();
      }
    }
    

    Neuen Datensatz erstellen

    void __fastcall TForm1::Neu1Click(TObject *Sender)
    {
      if(SaveDialog1->Execute() == true)
      {
        DateiName = SaveDialog1->FileName;
        dat_io.open(DateiName.c_str(),ios::binary|ios::trunc);
        Dat_Open = true;
      }
    }
    

    Ausgefüllte Felder als Datensatz schreiben

    void __fastcall TForm1::B_NeuClick(TObject *Sender)
    {
      //Textfelder auslesen & Datensatz zuweisen!
      strcpy(myDat.Nachname,    E_Nachname->Text.c_str());
      strcpy(myDat.Vorname,     E_Vorname->Text.c_str());
      strcpy(myDat.Strasse,     E_Strasse->Text.c_str());
      strcpy(myDat.Nr,          E_NR->Text.c_str());
      strcpy(myDat.Ort,         E_ORT->Text.c_str());
      myDat.PLZ                 =StrToInt(E_PLZ->Text);
      strcpy(myDat.Tel,         E_TEL->Text.c_str());
      strcpy(myDat.email,       E_email->Text.c_str());
      strcpy(myDat.Geburtsdatum,E_Geburtsdatum->Text.c_str());
    
      //Datensatz an die Datei anhängen Anpassen der Größe
      dat_io.write((char*) & myDat, sizeof(myDat));
    }
    

    So bis hier Funktioniert alles!

    Speichern

    void __fastcall TForm1::Speichern1Click(TObject *Sender)
    {
      if(SaveDialog1->Execute() == true)
      {
        DateiName = SaveDialog1->FileName;
        dat_io.open(DateiName.c_str(),ios::binary | ios::app);
    
        dat_io.write((char*) & myDat, sizeof(myDat));
        Dat_Open = true;
      }
    }
    

    Laden:

    void __fastcall TForm1::Laden1Click(TObject *Sender)
    {
      if(OpenDialog1->Execute() == true)
      {
       DateiName = OpenDialog1->FileName;
       dat_in.open(DateiName.c_str(),ios::failbit | ios::in | ios::binary | ios::app);
    
       if(dat_in.is_open())
       {
         dat_in.get((char*)& myDat, sizeof (myDat));
         //dat_in.read((char*)& myDat, sizeof(myDat));
         //dat_in.read(DateiName.c_str(), sizeof(myDat));
         //dat_in.get((char*)& myDat, sizeof (myDat));
    
         //Werte in die Edit Felder ausgeben
         E_Nachname->Text      = myDat.Nachname;
         E_Vorname->Text       = myDat.Vorname;
         E_Strasse->Text       = myDat.Strasse;
         E_NR->Text            = myDat.Nr;
         E_ORT->Text           = myDat.Ort;
         E_PLZ->Text           = IntToStr(myDat.PLZ);
         E_TEL->Text           = myDat.Tel;
         E_email->Text         = myDat.email;
         E_Geburtsdatum->Text  = myDat.Geburtsdatum;
    
         Dat_Open = true;
         DatensatzNR();
        }
      }
    }
    //---------------------------------------------------------------------------
    

    Datensatzzahl:

    void TForm1::DatensatzNR(void)
    {
       DateiName = OpenDialog1->FileName;
       dat_in.open(DateiName.c_str(),ios::in | ios::binary | ios::app);
    
       if(dat_in.is_open())
       {
        //seekg sucht das Ende des Datensatzes
        dat_in.seekg (ifstream::beg,ifstream::end);
        //tellg --> gibt die Größe in Bytes an (Gesammtgröße des Datensatzes)
        int nBytes=dat_in.tellg();
        //Ermitteln der Größe eines Datensatzes
        int nmyDat = sizeof (myDat);
        //die ermittelte Gesamtgröße geteilt durch die Datensatzgröße
        int n = nBytes / nmyDat;
    
        /*Datensatznummer in der Statusbar ausgeben*/
        SB1->Panels->Items[1]->Text=IntToStr(n);
       }
    }
    

    Vielen dank für die Hilfe 😃



  • Hallo

    wenn du schon mit dem BCB arbeitest, warum nimmst du nicht einfach TStringList, um die Daten zu sammeln und in eine Datei zu schreiben/daraus zu laden? Das würde den Code sehr vereinfachen, und sicher auch den Fehler umgehen.

    bis bald
    akari



  • Hi, ja da hast du recht...
    Jedoch beschäftige ich mich ja gerade mit Streams und wollte dies Progie so wie ichs gestaltet habe erstmal zuende bringen, einfach der Übung wegen!

    Denn ich will ja nicht vor dem Prob wegrennen sondern es bewältigen denn nur so lernt man ja Proggen ^^

    hier bin mit dem Laden und zählen weitergekommen habe nen wenig weiter getüftelt... fertig ist's noch nicht... und fehlerfrei auch nicht aber die funktionen sind etwas mehr gegeben ^^

    void TForm1::DatensatzNR(int Byte,int myDat)
    {
      //die ermittelte Gesamtgröße geteilt durch die Datensatzgröße
      int n = Byte/myDat;
    
      /*Datensatznummer in der Statusbar ausgeben*/
      SB1->Panels->Items[1]->Text=IntToStr(n);
    }
    
    void __fastcall TForm1::Laden1Click(TObject *Sender)
    {
      if(OpenDialog1->Execute() == true)
      {
        DateiName = OpenDialog1->FileName;
        dat_in.open(DateiName.c_str(),ios::in | ios::binary);
    
        if(!dat_in.is_open())
        {
          //Datei ist nicht offen!
          Application->MessageBox("Ihr Datensatz konnte nicht geöffnet werden.", "! FEHLER !", MB_OK);
        }
        else
        {
          //Werte in die Edit Felder ausgeben
          dat_in.read((char*)& myDat, sizeof(myDat));
          E_Nachname->Text      = myDat.Nachname;
          E_Vorname->Text       = myDat.Vorname;
          E_Strasse->Text       = myDat.Strasse;
          E_NR->Text            = myDat.Nr;
          E_ORT->Text           = myDat.Ort;
          E_PLZ->Text           = IntToStr(myDat.PLZ);
          E_TEL->Text           = myDat.Tel;
          E_email->Text         = myDat.email;
          E_Geburtsdatum->Text  = myDat.Geburtsdatum;
    
          Dat_Open = true;
    
          //seekg sucht das Ende des Datensatzes
          dat_in.seekg (ifstream::beg,ifstream::end);
          //nBytes --> tellg --> gibt die Größe in Bytes an (Gesammtgröße des Datensatzes)
          nBytes=dat_in.tellg();
          //nmyDat --> Ermitteln der Größe eines Datensatzes
          nmyDat = sizeof (myDat);
    
          DatensatzNR(nBytes,nmyDat);
        }
      }
    }
    //---------------------------------------------------------------------------
    

    Danke dir aber für deine Antwort



  • Hallo

    fertig ist's noch nicht... und fehlerfrei auch nicht

    Hm... erwartest du jetzt eine Antwort? Wenn ja, erklär doch erstmal präzise den Fehler und was du wissen willst.

    bis bald
    akari



  • Hi @ akari

    Also mein Problem liegt darin, das er die Strings alle ausgibt jedoch gibt er zuviel aus in den einzelnen Edit Feldern!

    Versuche das mal andres zu erklären!

    1.E_Feld --> Müller //Funktioniert
    2.E_Feld --> Mannfred Am H //Gibt noch die strasse mit aus
    usw.

    wie könnte ich die string in den Editfeldern begrenzen ?
    Habe da nichts für gefunden habe das jetzt über "dat_in.get()" gelöst jedoch habe ich da mit dem "integer - Wert" Probleme der auch Binäre gespeichert wurde!

    Hier ist meine neue Ausgabe:

    Die Lade Funktion:

    //---------------------------------------------------------------------------
    void __fastcall TForm1::Laden1Click(TObject *Sender)
    {
      if(dat_in.is_open()||dat_io.is_open())
      {
        dat_io.close();
        dat_in.close();
      }
    
      if(OpenDialog1->Execute() == true)
      {
        DateiName = OpenDialog1->FileName;
        dat_in.open(DateiName.c_str(),ios::in | ios::binary);
    
        if(!dat_in.is_open())
        {
          //Datei ist nicht offen!
          Application->MessageBox("Ihr Datensatz konnte nicht geöffnet werden.", "! FEHLER !", MB_OK);
        }
        else
        {
          //Datei offen
          //Daten-Werte in die Edit Felder ausgeben
    
          Ausgabe_Daten();
    
          Dat_Open = true;
    
          //seekg sucht das Ende des Datensatzes
          dat_in.seekg (ifstream::beg,ifstream::end);
          //nBytes --> tellg --> gibt die Größe in Bytes an (Gesammtgröße des Datensatzes)
          nBytes=dat_in.tellg();
          //nmyDat --> Ermitteln der Größe eines Datensatzes
          nmyDat = sizeof (myDat);
    
          DatensatzNR(nBytes,nmyDat);
        }
      }
    }
    //---------------------------------------------------------------------------
    

    Habe zwecks übersichtlichkeit eine neue Funktion erstellt!
    void Ausgabe_Daten(void);
    Hier:

    //---------------------------------------------------------------------------
    void TForm1::Ausgabe_Daten(void)
    {
         /*
          dat_in.read((char*)& myDat, sizeof(myDat));
    
          E_Nachname->Text     = myDat.Nachname;
          E_Vorname->Text      = myDat.Vorname;
          E_Strasse->Text      = myDat.Strasse;
          E_NR->Text           = myDat.Nr;
          E_ORT->Text          = myDat.Ort;
          E_PLZ->Text          = IntToStr(myDat.PLZ);
          E_TEL->Text          = myDat.Tel;
          E_email->Text        = myDat.email;
          E_Geburtsdatum->Text = myDat.Geburtsdatum;
        */
          char ch;
          AnsiString buff;
          int Postl;
    
          for(int i=0;i<=sizeof(myDat.Nachname)-1 ;i++)
          {
            dat_in.get(ch);
            buff = buff + ch;
            E_Nachname->Text = buff;
          }
    
          buff ="";
    
          for(int i=0;i<=sizeof(myDat.Vorname)-1;i++)
          {
            dat_in.get(ch);
            buff = buff + ch;
            E_Vorname->Text = buff;
          }
    
          buff ="";
    
          for(int i=0;i<=sizeof(myDat.Strasse)-1;i++)
          {
            dat_in.get(ch);
            buff = buff + ch;
            E_Strasse->Text = buff;
          }
    
          buff ="";
    
          for(int i=0;i<=sizeof(myDat.Nr)-1;i++)
          {
            dat_in.get(ch);
            buff = buff + ch;
            E_NR->Text = buff;
          }
    
          buff ="";
    
          for(int i=0;i<=sizeof(myDat.Ort);i++)
          {
            dat_in.get(ch);
            buff = buff + ch;
            E_ORT->Text = buff;
          }
    
          buff ="";
    
          for(int i=0;i<=sizeof(myDat.PLZ)+1;i++)
          {
            dat_in.get(ch);
            Postl = ch;
            buff = IntToStr(Postl);
            E_PLZ->Text = buff;
          }
    
          buff ="";
    
          for(int i=0;i<=sizeof(myDat.Tel)-1;i++)
          {
            dat_in.get(ch);
            buff = buff + ch;
            E_TEL->Text = buff;
          }
    
          buff ="";
    
          for(int i=0;i<=sizeof(myDat.email)-1;i++)
          {
            dat_in.get(ch);
            buff = buff + ch;
            E_email->Text = buff;
          }
    
          buff ="";
    
          for(int i=0;i<=sizeof(myDat.Geburtsdatum);i++)
          {
            dat_in.get(ch);
            buff = buff + ch;
            E_Geburtsdatum->Text = buff;
          }
    }
    //---------------------------------------------------------------------------
    

    So bei dieser Art & Weise funktioniert alles bis auf die als Integer abgespeicherte PLZ!

    Mit der Speicher Funktion habe ich auch noch Probleme!
    Und zwar, wenn ich ios::app verwende speichert er den Datensatz nicht ab.
    Wenn ich es wie folgt verwende, speichert er in ab, jedoch nur einen Datensatz & auch nur blanko! also nen leeren Datensatz von 200 Byte ^^.
    KP warum! (beim öffnen nen automatisches trunk?)

    //---------------------------------------------------------------------------
    void __fastcall TForm1::Speichern1Click(TObject *Sender)
    {
      if(SaveDialog1->Execute() == true)
      {
        DateiName = SaveDialog1->FileName;
        dat_io.open(DateiName.c_str(),ios::binary);
        dat_io.write((char*) & myDat, sizeof(myDat));
        Dat_Open = true;
      }
    }
    //---------------------------------------------------------------------------
    

    So beim Speichern & Laden komme ich nicht weiter voran... Wenn jemand bzw. du akari,(da ja bis dato noch niemand weiter geschrieben hat ;)) nen Tip hat wie ich evt. die erste Lösung Splitten kann oder, in der 2. Lösung vernünftig die PLZ ausgeben kann wäre ich sehr dankbar! 🙂

    Die Datensatznummer funktioniert, werde mich jetzt mit dem Switschen beschäftigen (also vor, zurück, An den Anfang, An den Ende)

    MFG
    Dennis alias cyby



  • Hallo

    ich denke du solltest dir einfach mal dieses Thema aus der C++ FAQ anschauen, um deine Stream-Operationen in Ordnung zu bringen. Es gibt dort ein Absachnitt "Das letzte Beispiel zeigt wie man Datensätze schreiben und lesen kann."
    Und dann kannst du auch char[] direkt an AnsiString übergeben, das must du nicht char für char kopieren.

    /Edit : und statt der char[] im Struct kannst du auch gleich besser std:string oder AnsiString verwenden.

    bis bald
    akari



  • Danke dir ziehe ich mir mal rein...
    Nur denke ich steht das auch nicht mehr als in meinen Büchern ^^ so beim flüchtigen überfliegen ^^

    aber werde mir das jetzt mal in ruhe zu gemüte führen...

    MFG
    Dennis alias cyby



  • Hi stehen doch nen paar antworten drin die ich gesucht habe *g*
    danke dir nochmal wenn ich weiter probs habe oder absolute verständnisprobs werde ich mich nochmal melden!

    thx
    🙂


Anmelden zum Antworten