Zugriffsprobleme bei Strings

mesod

Grünschnabel
Hi,

ich programmiere gerade eine kleine Statistikübersicht für einen Angelverein, Daten werden eingelesen aber ich kann Sie nicht verändern und auch keine neuen hinzufügen, es wird nur das eingelesen was in der *.dat steht anbei die codes, weiß echt nicht mehr weiter

Code:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "data.h"
//---------------------------------------------------------------------------
//  Konstruktor der FischInfo-Struktur
//---------------------------------------------------------------------------
FischInfo::FischInfo()
{
  sgedit1  = "Nicht definiert";
  sgedit2 = "Nicht definiert";
  sgedit3 = "leer";
};
//---------------------------------------------------------------------------
//  Konstruktor der FischData-Klasse
//---------------------------------------------------------------------------
FischData::FischData()
{
  pFisch = new TList;     // Zeigerliste erzeugen
  bgDataChanged = false;  // "geändert"-Flag
}

//---------------------------------------------------------------------------
//  Destruktor der FischData-Klasse
//---------------------------------------------------------------------------
FischData::~FischData()
{
  if(pFisch != NULL)
  {
    pFisch -> Clear();
    delete pFisch;
    pFisch = NULL;
  }
}

//---------------------------------------------------------------------------
//  Einlesen der Daten aus Datei
//---------------------------------------------------------------------------
bool FischData::LoadFromAscii()
{
  TStringList* stlData = new TStringList;
  try
  {
    AnsiString slDataFile = ExtractFilePath(ParamStr(0)) + "\\data.dat";
    if(FileExists(slDataFile))
    {
      // Dateiinhalt in die Stringliste laden:
      stlData -> LoadFromFile(slDataFile);

      // Falls Datei nicht leer:
      if(stlData -> Count)
      {

        // Anzahl der Bücher entspricht der Anzahl der Zeilen-1:
        int ilFischCount = stlData -> Count -1;

        // Zeilen parsen, Datenaaray füllen:
        for(int ilFischNo = 0; ilFischNo < ilFischCount; ilFischNo++)
        {
          AddFisch();

          SetEdit1(ilFischNo, ExtractFieldContents(
            stlData -> Strings[ilFischNo+1], FIELD_SEP, 1));

          SetEdit2(ilFischNo, ExtractFieldContents(
            stlData -> Strings[ilFischNo+1], FIELD_SEP, 2));

          SetEdit3(ilFischNo, ExtractFieldContents(
            stlData -> Strings[ilFischNo+1], FIELD_SEP, 3));
...etc für alle weiteren editfelder
                  }
        bgDataChanged = false;
        return true;
      }
      else return false;
    }
    else return false;
  }
  catch (...)
  {
    if(stlData != NULL) { delete stlData; stlData = NULL; }
    return false;
  }
}

//---------------------------------------------------------------------------
//  Speichern der Daten in der Ascii-Datei
//---------------------------------------------------------------------------
bool FischData::SaveToAscii()
{
  TStringList* stlData = new TStringList;
  try
  {

    // Zeilen parsen, Datenaaray füllen:
    AnsiString slTmpData = EmptyStr;

    for(int ilFischNo = 0; ilFischNo < GetFischCount(); ilFischNo++)
    {

      slTmpData = GetEdit1(ilFischNo) + FIELD_SEP;

      slTmpData += GetEdit2(ilFischNo) + FIELD_SEP;

      slTmpData += GetEdit3(ilFischNo) + FIELD_SEP;
..etc 
      

      // Datensatz als Zeile an die Stringliste anhängen:
      stlData -> Add(slTmpData);
    }
    stlData -> SaveToFile(ExtractFilePath(ParamStr(0)) + "\\data.dat");
    bgDataChanged = false;
    return true;
  }
  catch (...)
  {
    if(stlData != NULL) { delete stlData; stlData = NULL; }
    return false;
  }
}

//---------------------------------------------------------------------------
//  Hinzufügen eines neuen Datensatzes
//---------------------------------------------------------------------------
void FischData::AddFisch()
{
  pFisch -> Add(new FischInfo);
  bgDataChanged = true;
}

//---------------------------------------------------------------------------
//  Löschen eines Datensatzes
//---------------------------------------------------------------------------
bool FischData::DelFisch(int ilIndex)
{
  if(ilIndex >= 0 && ilIndex < pFisch -> Count)
  {
    pFisch -> Delete(ilIndex);
    pFisch -> Capacity = pFisch -> Count;
    bgDataChanged = true;
    return true;
  }
  else return false;
}

//---------------------------------------------------------------------------
//  Gibt die Anzahl der Datensätze zurück
//---------------------------------------------------------------------------
int FischData::GetFischCount()
{
  return pFisch -> Count;
}

//---------------------------------------------------------------------------
//  Gibt Edit1 zurück
//---------------------------------------------------------------------------
AnsiString FischData::GetEdit1(int ilIndex)
{
  if(ilIndex >= 0 && ilIndex < pFisch -> Count)
    return ((FischInfo*)pFisch ->Items[ilIndex]) -> sgedit1;
  else return "Nicht definiert";
}
//---------------------------------------------------------------------------
//  Setzt Edit1
//---------------------------------------------------------------------------
void FischData::SetEdit1(int ilIndex, AnsiString slValue)
{
  if(ilIndex >= 0 && ilIndex < pFisch -> Count)
  {
    if(GetEdit1(ilIndex) != slValue)
    {
      ((FischInfo*)pFisch ->Items[ilIndex])-> sgedit1 = slValue;
      bgDataChanged = true;
    }
  }
}
//---------------------------------------------------------------------------
//  Gibt Edit2 zurück
//---------------------------------------------------------------------------
AnsiString FischData::GetEdit2(int ilIndex)
{
  if(ilIndex >= 0 && ilIndex < pFisch -> Count)
    return ((FischInfo*)pFisch ->Items[ilIndex]) -> sgedit2;
  else return "Nicht definiert";
}
//---------------------------------------------------------------------------
//  Setzt Edit2
//---------------------------------------------------------------------------
void FischData::SetEdit2(int ilIndex, AnsiString slValue)
{
  if(ilIndex >= 0 && ilIndex < pFisch -> Count)
  {
    if(GetEdit2(ilIndex) != slValue)
    {
      ((FischInfo*)pFisch ->Items[ilIndex])-> sgedit2 = slValue;
      bgDataChanged = true;
    }
  }
}
//---------------------------------------------------------------------------
//  Gibt Edit3 zurück
//---------------------------------------------------------------------------
AnsiString FischData::GetEdit3(int ilIndex)
{
  if(ilIndex >= 0 && ilIndex < pFisch -> Count)
    return ((FischInfo*)pFisch ->Items[ilIndex]) -> sgedit3;
  else return "Nicht definiert";
}
//---------------------------------------------------------------------------
//  Setzt Edit3
//---------------------------------------------------------------------------
void FischData::SetEdit3(int ilIndex, AnsiString slValue)
{
  if(ilIndex >= 0 && ilIndex < pFisch -> Count)
  {
    if(GetEdit3(ilIndex) != slValue)
    {
      ((FischInfo*)pFisch ->Items[ilIndex])-> sgedit3 = slValue;
      bgDataChanged = true;
    }
  }
}

etc....
//---------------------------------------------------------------------------
//  Konvertiert String zu Double unabhängig davon, ob Punkt oder Komma
//  als Dezimaltrennzeichen verwendet wird
//---------------------------------------------------------------------------
double ConvertToDouble(AnsiString sValueString)
{
  double dResultValue = ERR_VALUE;
  if(sValueString == EmptyStr) return ERR_VALUE;
  
  try
  {
    int iNonDigitCounter = 0, iNonDigitPosition = 0;
    for(int iCharNo = 1; iCharNo <= sValueString.Length(); iCharNo++)
    {
      if(!isdigit(sValueString[iCharNo]))
      {
        if(sValueString[iCharNo] != '+' && sValueString[iCharNo] != '-')
        {
          iNonDigitPosition = iCharNo;
          iNonDigitCounter++;
        }
      }
    }
    if(iNonDigitCounter < 2 && iNonDigitCounter > 0)
    {
      if(sValueString[iNonDigitPosition] == DecimalSeparator)
      { dResultValue = sValueString.ToDouble(); }
      else if (sValueString[iNonDigitPosition] == '.' ||
        sValueString[iNonDigitPosition] == ',')
      {
        sValueString[iNonDigitPosition] = DecimalSeparator;
        dResultValue = sValueString.ToDouble();
      }
    }
    else if (!iNonDigitCounter)
    {
      dResultValue = sValueString.ToDouble();
    }
    return dResultValue;
  }
  catch(...) { return ERR_VALUE; }
}
//-----------
// Gibt "geändert-Flag zurück
//----------
bool FischData::Changed()
{
return bgDataChanged;
}
//---------------------------------------------------------------------------
//  Beschreibung: Extrahiert Feldinhalt aus dem String mit getr. Feldern
//  Parameter:    1. der Ausgangsstring       als String
//                2. der Feldertrennstring    als String
//                3. die Feldnummer           als Integer
//---------------------------------------------------------------------------

AnsiString ExtractFieldContents(AnsiString slInputStr,
  AnsiString slSeparator, int ilField)
{
  // falls Feldnummer oder Separator ungültig, leeren String zurückgeben:
  if(ilField < 1 || slSeparator == EmptyStr)
    return EmptyStr;

  // Nummer des letzten Buchstaben des gesuchten Teilstrings:
  int ilLastChar = 0;

  // Falls gesuchtes Feld gleich als erstes kommt:
  if(ilField == 1)
  {
    // Falls keine Trennzeichen im Hauptstring vorhanden:
    if(slInputStr.Pos(slSeparator) < 1)
      // ganzer String ist unser:
      ilLastChar = slInputStr.Length();
    else
      // ansonsten letzten Buchstaben merken:
      ilLastChar = slInputStr.Pos(slSeparator) - 1;
  }
  // falls nicht 1. Feld gesucht:
  else
  {
    // in Schleife nach den Trennzeichen suchen
    for(int ilFieldNo = 1; ilFieldNo < ilField; ilFieldNo++)
    {
      // Falls Trennzeichen gefunden:
      if(slInputStr.Pos(slSeparator) > 0)
      {
        // nicht benötigtes Feldes killen:
        slInputStr = slInputStr.SubString(slInputStr.Pos(slSeparator)+1,
          slInputStr.Length() - slInputStr.Pos(slSeparator) + 1);
      }
      // Falls keine Trennzeichen mehr, obwohl welche da sein sollten,
      // String killen:
      else slInputStr = EmptyStr;
    }

    // Falls im geköpften String keine Leerzeichen mehr vorhanden,
    // ganzen String nehmen
    if(slInputStr.Pos(slSeparator) < 1)
      ilLastChar = slInputStr.Length();
    // ansonsten letzten Buchstaben merken:
    else
      ilLastChar = slInputStr.Pos(slSeparator) - 1;
  }

  // falls überhaupt noch irgendetwas vom Hauptstring übrig:
  if(slInputStr.Length() > 0 && ilLastChar <= slInputStr.Length())
    // Feldinhalt herausschneiden und zurückgeben
    return slInputStr.SubString(1, ilLastChar);
  else
    // ansonsten leeren String zurückgeben:
    return EmptyStr;
}


//---------------------------------------------------------------------------
#pragma package(smart_init)
Code:
//---------------------------------------------------------------------------
#ifndef dataH
#define dataH

#define  FIELD_SEP "\t"         // Feldertrennzeichen für die Datendatei(Tab)
#define  ERR_VALUE  0.0         // "Fehlerwert" für die Konvertierfunktionen

//  Extrahiert Feldinhalt aus dem String mit getr. Feldern
AnsiString ExtractFieldContents(AnsiString slInputStr,
  AnsiString slSeparator, int ilField);

//  Konvertiert String zu Double unabhängig davon, ob Punkt oder Komma
//  als Dezimaltrennzeichen verwendet wird
double ConvertToDouble(AnsiString sValueString);


//---------------------------------------------------------------------------
// Struktur für die Daten
struct FischInfo
{
  FischInfo();               // Konstruktor
  AnsiString sgedit1;
  AnsiString sgedit2;
  AnsiString sgedit3;
etc...
    };
//---------------------------------------------------------------------------
//  FischData-Klasse
//---------------------------------------------------------------------------
class FischData
{
  private:

    // Liste der Zeiger auf die BookData-Instanzen:
    TList * pFisch;


  public:

    FischData();                               // Konstruktor
    ~FischData();                              // Destruktor

    bool bgDataChanged;

    bool LoadFromAscii();
    bool SaveToAscii();

    void AddFisch();
    bool DelFisch(int ilIndex);

    int GetFischCount();

    AnsiString GetEdit1(int ilIndex);
    void SetEdit1(int ilIndex, AnsiString slValue);

    AnsiString GetEdit2(int ilIndex);
    void SetEdit2(int ilIndex, AnsiString slValue);

    AnsiString GetEdit3(int ilIndex);
    void SetEdit3(int ilIndex, AnsiString slValue);

    etc....

    bool Changed();
};

//---------------------------------------------------------------------------
#endif
Code:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "form.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::exitClick(TObject *Sender)
{
Close();        
}
//---------------------------------------------------------------------------
// EventHandler für den Click auf die Listbox mit der
// Aufsstellung Mitglieder:
//---------------------------------------------------------------------------
void __fastcall TForm1::ListBox1Click(TObject *Sender)
{
  if(ListBox1->ItemIndex >= 0)
  {
    Edit1 -> Text        = pData -> GetEdit1(ListBox1 -> ItemIndex);
    Edit2 -> Text        = pData -> GetEdit2(ListBox1 -> ItemIndex);
    Edit3 -> Text        = pData -> GetEdit3(ListBox1 -> ItemIndex);
    Edit4 -> Text        = pData -> GetEdit4(ListBox1 -> ItemIndex);
etc.....
    del -> Enabled    = true;

  }
  else
  {
    Edit1 -> Text        = EmptyStr;
    Edit2 -> Text       = EmptyStr;
    Edit3 -> Text        = EmptyStr;
    Edit4 -> Text        = EmptyStr;
etc....
    del -> Enabled    = false;
  }
}
//---------------------------------------------------------------------------
// OnExit-Ereignis der Editboxen
//---------------------------------------------------------------------------
void __fastcall TForm1::editExit(TObject *Sender)
{
  if(Sender == Edit1)
  {
    pData -> SetEdit1(ListBox1 -> ItemIndex, Edit1 -> Text);
    ListBox1 -> Items -> Strings[ListBox1 -> ItemIndex] = Edit1 -> Text;
  }
  else if(Sender == Edit2)
    pData -> SetEdit2(ListBox1 -> ItemIndex, Edit2 -> Text);
  else if(Sender == Edit3)
    pData -> SetEdit3(ListBox1 -> ItemIndex, Edit3 -> Text);
etc....


}
//---------------------------------------------------------------------------
// Hinzufügen neuer Mitglieder
//---------------------------------------------------------------------------
void __fastcall TForm1::addClick(TObject *Sender)
{
  pData -> AddFisch();
  ListBox1 -> Items -> Add(pData->GetEdit1(pData->GetFischCount()-1));
  ListBox1 -> ItemIndex = pData->GetFischCount()-1;
  ListBox1Click(this);
}
//---------------------------------------------------------------------------
// Löschen eines Datensatzes
//---------------------------------------------------------------------------
void __fastcall TForm1::delClick(TObject *Sender)
{
  if(ListBox1->Items->Count>1)
  {
    if(pData -> DelFisch(ListBox1->ItemIndex))
    {
      int ilOldIndex = ListBox1->ItemIndex;
      ListBox1->Items->Delete(ListBox1->ItemIndex);
      if(ilOldIndex>0) ListBox1->ItemIndex=ilOldIndex-1;
      else ListBox1->ItemIndex=0;
    }
  }
  else ListBox1->ItemIndex=0;
  ListBox1Click(this);
}
//---------------------------------------------------------------------------
// Initialisierung // Überprüfung der Datendatei
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
pData = new FischData;
  if(!pData->LoadFromAscii())
    Application->MessageBox("Fehler beim Laden der Datendatei !", "Fehler!",
        MB_OK+MB_ICONEXCLAMATION);
  InitFormControls();
}
//---------------------------------------------------------------------------
// Initialisierung der Steuerelemente auf dem Formular
//---------------------------------------------------------------------------
void __fastcall TForm1::InitFormControls()
{

  ListBox1 -> Items -> Clear();
  for(int ilIndex = 0; ilIndex < pData->GetFischCount(); ilIndex++)
    ListBox1 -> Items -> Add(pData->GetEdit1(ilIndex));

  if(ListBox1 -> Items -> Count > 0) ListBox1 -> ItemIndex = 0;

  // um die restlichen Steuerelemente zu initialisieren:
  ListBox1Click(this);
}
//---------------------------------------------------------------------------
//  Wird vom KeyDown-Ereignis div. Float-Editboxen aufgerufen
//  und killt alle ungültigen Tastenanschläge
//---------------------------------------------------------------------------
void __fastcall TForm1::enterFloatOnly(TObject *Sender, char &Key)
{
  if((Key == '.' || Key == ',') && !dynamic_cast<TEdit*>(Sender) ->
    Text.Pos(AnsiString(DecimalSeparator)) > 0)
  Key = DecimalSeparator;

  else if((Key < '0' || Key > '9') && Key != 8)
    Key = 0;
}

//---------------------------------------------------------------------------
// Aufräumen
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
  if(pData != NULL)
  {
    if(pData -> Changed())
      pData -> SaveToAscii();
    delete pData;
    pData = NULL;
  }
}

ist mein Erstes etwas größere Projekt, also nicht zu sehr über den Stil meckern ;)

Im Voraus schonmal DANKE für alle hilfreiche Antworten

Gruß
Christian
 
Es würde mir sehr helfen, wenn du mitteilen könntest, was genau nicht funktioniert und welcher von dir gepostete Code eigentlich was darstellt.
 

Neue Beiträge

Zurück