Delphi-PRAXiS
Seite 1 von 2  1 2   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Probleme mit eigener Klasse (https://www.delphipraxis.net/3211-probleme-mit-eigener-klasse.html)

Luckie 28. Feb 2003 21:20


Probleme mit eigener Klasse
 
Ich habe mir eine eigene Klasse entworfen um einen String der durch Separatoren getrennt ist in einzelne Strings zu zerlegen.
Delphi-Quellcode:
type TSplitString = class
 private
   FString2Split : String;
   FSepChar     : Char;
   FStrings     : TSplitStrArray;
   FStringsCount : Integer;
   FSepPos      : array of Integer;
   procedure SetSplitString(SplitStr: String);
   procedure SetSepChar(sep: Char);
   procedure SetSepPos;
   procedure SplitString;
 public
   constructor create(SplitStr: String; sep: Char);
   property String2Split: String read FString2Split write SetSplitString;
   property SepChar: Char read FSepChar write SetSepChar;
   function StringsCount: Integer;
   property SplitStringEx: TSplitStrArray read FStrings write SplitString; { hier kommt die Meldung: "Inkompatible Typen" }
end;

constructor TSplitString.create(SplitStr: String; sep: Char);
var
  i : Integer;
begin
  FStringsCount := 0;
  SetSplitString(SplitStr);
  SetSepChar(sep);
  if SplitStr[length(SplitStr)] <> sep then
    SplitStr := SplitStr+sep;
  for i := 1 to length(SplitStr)-1 do
  begin
    if SplitStr[i] = sep then Inc(FStringsCount);
  end;
  SetSepPos;
end;

procedure TSplitString.SetSepPos;
var
  i, j : Integer;
begin
  j := 0;
  setlength(FSepPos, FStringsCount+1);
  FSepPos[0] := 0;
  for i := 1 to length(FString2Split)-1 do
  begin
    if FString2Split[i] = FSepChar then
    begin
      FSepPos[j+1] := i;
      Inc(j);
    end;
  end;
end;

procedure TSplitString.SetSplitString(SplitStr: String);
begin
  if SplitStr = '' then
    Messagebox(0, 'Die Zeichenfolge ist leer.', 'Hinweis - TSplitString', MB_ICONINFORMATION);
  FString2Split := SplitStr;
end;

procedure TSplitString.SetSepChar(sep: Char);
begin
  if sep = '' then
    Messagebox(0, 'Das Trennzeichen ist leer.', 'Hinweis - TSpliString', MB_ICONINFORMATION);
  FSepChar := sep;
end;

function TSplitString.StringsCount: Integer;
begin
  result := FStringsCount;
end;

procedure TSplitString.SplitString;
var
  i  : Integer;
begin
  setlength(FStrings, FStringsCount);
  for i := 0 to FStringsCount-1 do
  begin
    FStrings[i] := copy(FString2Split, FSepPos[i], FsepPos[i+1]-FSepPos[i]);
  end;
end;
An der besagten Stelle kommt eben diese Fehlermeldung.
Delphi-Quellcode:
property SplitStringEx: TSplitStrArray read FStrings write SplitString;
Soll zum einen das Array mit den aufgeteilten Strings zurückgeben und zum anderen es füllen. Aber irgendwie mache ich da was falsch.
Verbesserungsvorschläge und Vereinfachungen der Klasse sind auch herzlich willkommen.

Snoop007 28. Feb 2003 21:32

hi,
Delphi-Quellcode:
   
property String2Split: String read FString2Split write SetSplitString;
   property SepChar: Char read FSepChar write SetSepChar;
   function StringsCount: Integer;
   property SplitStringEx: TSplitStrArray read FStrings write SplitString; { hier kommt die Meldung: "Inkompatible Typen" }
mach mal
Delphi-Quellcode:
function StringsCount: Integer;
   property String2Split: String read FString2Split write SetSplitString;
   property SepChar: Char read FSepChar write SetSepChar;
   property SplitStringEx: TSplitStrArray read FStrings write SplitString; { hier kommt die Meldung: "Inkompatible Typen" }

Luckie 28. Feb 2003 21:37

Öhm, was hast du jetzt gemacht außer die Reihenfolge zu ändern? (Was übrigens auch nicht hilft. :( )

CalganX 28. Feb 2003 21:40

Die Funktion, die du in Write schreibst, muss, glaube ich, einen Parameter des Typs erhalten, der auch die Property hat.
So ungefähr... :roll:

Chris

PS: Ich weiß: ist ziemlich unverständlich!

Luckie 28. Feb 2003 21:50

OK, habe es jetzt so geändert:
Delphi-Quellcode:
type
  TSplitStrArray = array of String;

type TSplitString = class
 private
   FString2Split : String;
   FSepChar     : Char;
   FStrings     : TSplitStrArray;
   FStringsCount : Integer;
   FSepPos      : array of Integer;
   procedure SetSplitString(SplitStr: String);
   procedure SetSepChar(sep: Char);
   procedure SetSepPos;
   procedure SplitString(sArray: TSplitStrArray);
 public
   constructor create(SplitStr: String; sep: Char);
   function StringsCount: Integer;
   property String2Split: String read FString2Split write SetSplitString;
   property SepChar: Char read FSepChar write SetSepChar;
   property SplitStringEx: TSplitStrArray read FStrings write SplitString(sArray: TSplitStrArray); { Zeile 192 }
end;
Jetzt sagt er mir in der gleichen Zeile wie oben:
Zitat:

[Fehler] AdressDB.dpr(192): ';' erwartet, aber '(' gefunden
[Fehler] AdressDB.dpr(192): 'END' erwartet, aber ')' gefunden
Bei der ersten Meldung steht der Cursor direkt vor sArray. Beim zweiten vor dem Abschließenden Semikolon.

Luckie 28. Feb 2003 22:05

OK, OK, OK. Ich habs. Die letzte Zeile muß natürlich so
Delphi-Quellcode:
property SplitStringEx: TSplitStrArray read FStrings write SplitString;
heißen.

CalganX 28. Feb 2003 22:26

Jetzt funktionierts? :?:

Chris

Luckie 28. Feb 2003 22:28

Mehr oder weniger. Kompilieren tuit er, er macht nur nicht das, was ich will.

jbg 28. Feb 2003 22:54

Hier mal eine Nachbildung des Explode-Befehls von PHP. Das dürft wohl in etwa das sein, was du da in deine Klasse einprogrammieren willst.
Delphi-Quellcode:
uses Types;

// Explode trennt S in die durch Separator getrennten Elemente auf. Wenn Limit
// > 0 ist, so werden max. Limit Elemente getrennt, wobei im letzen Element
// die Restzeichenkette steht.
{type
  TStringDynArray = array of string;}

function Explode(const Separator, S: string; Limit: Integer = 0): TStringDynArray;
var
  SepLen: Integer;
  F, P: PChar;
  ALen, Index: Integer;
begin
  SetLength(Result, 0);
  if (S = '') or (Limit < 0) then Exit;
  if Separator = '' then
  begin
    SetLength(Result, 1);
    Result[0] := S;
    Exit;
  end;
  SepLen := Length(Separator);
  ALen := Limit;
  SetLength(Result, ALen);

  Index := 0;
  P := PChar(S);
  while P^ <> #0 do
  begin
    F := P;
    P := AnsiStrPos(P, PChar(Separator));
    if (P = nil) or ((Limit > 0) and (Index = Limit - 1)) then P := StrEnd(F);
    if Index >= ALen then
    begin
      Inc(ALen, 5); // mehrere auf einmal um schneller arbeiten zu können
      SetLength(Result, ALen);
    end;
    SetString(Result[Index], F, P - F);
    Inc(Index);
    if P^ <> #0 then Inc(P, SepLen);
  end;
  if Index < ALen then SetLength(Result, Index); // wirkliche Länge festlegen
end;

Luckie 28. Feb 2003 22:59

Zitat:

Zitat von jbg
Hier mal eine Nachbildung des Explode-Befehls von PHP. Das dürft wohl in etwa das sein, was du da in deine Klasse einprogrammieren willst.

Du hast es erfaßt. :mrgreen: Und ich werde wohl deinen Code nehmen. Denn mit einer Klasse schießt man damit wohl mit Spatzen auf Kanonen. Trotzdem bleibt mein Wunsch aus dem anderen Topic bestehe, was man verbessern könnte oder ändern sollte. Dient ja auch der Übung.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:53 Uhr.
Seite 1 von 2  1 2   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz