Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Wort in einem String vergleichen


fritz_07 - Di 01.06.10 23:21
Titel: Wort in einem String vergleichen
Hallo an alle,

komme mal wieder nicht weiter.

Folgendes Problem:

Ich habe eine Variable Inhalt vom Typ String,dieser wird über ein Edit-Fenster ein Pfad zugewiesen.
Dann eine zweite Variable,die den zu suchenden Verzeichnisnamen enthält.Beide Stringwerte ändern sich hin und wieder.
Nun möchte ich überprüfen,ob in dem Pfad der Verzeichnisname vorkommt.
Eine geeignete Funktion,wäre z.B. die ContainsText,da beim Vergleich die Groß,-und Kleinschreibung nicht beachtet wird.
Diese Funktion erwartet aber eine const (laut Funktionsbeschreibung) und const sind doch nicht änderbar???


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure Button1.Click(Sender : TObject);
var Inhalt, Suche : String,

begin

 Inhalt := Edit1.Text;
 Suche  := Edit2.Text;

  If ContainsText()  then   //ab hier weiß ich nicht mehr weiter

end;



Gruß fritz_07


Moderiert von user profile iconNarses: Topic aus VCL (Visual Component Library) verschoben am Di 01.06.2010 um 23:22


Narses - Di 01.06.10 23:23

Moin!

In diesem Fall bedeutet das const etwas anderes: der Parameter wird in der Funktion nicht verändert (aber intern als Referenz weitergegeben, was ressourcenschonender ist). :idea:

Also, einfach mal ausprobieren! :zustimm:

cu
Narses


fritz_07 - Fr 04.06.10 23:50

Hallo Narses,

ich habe es ausprobiert und muß sagen,es funktioniert.

Warum verwendet man dann in der Funktionsdeklaration const,wenn er als solches nicht verwendet wird?

Bezieht sich das nur auf diesen Fall???
Zitat:

In diesem Fall bedeutet das const etwas anderes: der Parameter wird in der Funktion nicht verändert (aber intern als Referenz weitergegeben, was ressourcenschonender ist).


Wie sieht eigenlich ein Zeiger auf eine const aus?
Bitte ein Beispiel.


Gruß fritz_07


Delete - Fr 04.06.10 23:57

Das const bei einer Variablendeklaration hat mit dem const bei Parametern nichts zu tun. Bei Parametern legt es fest, wie die Parameter übergeben werden, ob by value (const) oder by reference (var).


Bergmann89 - Sa 05.06.10 00:03

Hey,

wie Narses schon sagte, da wird der Zeiger auf die Variable weitergegeben, um Ressourcen zu sparen. Und das ist bei allen Prozeduren/Funktionen so, bei denen die Paramerter als Konstante übergeben werden. Einen Zeiger auf eine Konstante gibts es eig. nicht, aber bei der Prozedur/Funktion ist das ja auch keine echte Konstante, sondern ein Zeiger auf eine Variable, bei der aber der Compiler das schreiben verbietet, wenn ich das richtig verstanden habe. So genau hab ich mich mit dem Thema noch nicht beschäftigt^^

€ @Luckie: Narses hat doch geschrieben, das bei const die Referenz übergeben wird, um Resourcen zu sparen. Kann es sein das du da was verwechselst? Weil CallByValue is ja einfach procedure Test(Value: Integer);
also ohne constoder var.

MfG Bergmann


Delete - Sa 05.06.10 00:21

by value bedeutet, dass eine Kopie des Wertes der Variablen übergeben wird. by refernece wird ein Zeiger auf den Speicherplatz übergeben.

Und ich glaube, ich habe mich geirrt.
var: by reference, es wird ein Zeiger auf die Speicherstelle übergeben, der Parameter kann in der Prozedur geändert werden und das wirkt sich auf den Wert der Speicherstelle aus.
const: by value, der Parameter wird als Kopie übergeben und kann nicht geändert werden.
gar nichts: Der Parameter wird als Kopie übergeben und kann geändert werden, aber das wirkt sich nicht auf den Wert der Speicherstelle aus.

So sollte es passen.


elundril - Sa 05.06.10 01:19

Gilt aber nur wenn die Variablen keine Objekte sind. In diesem Fall werden sie immer als Referenz übergeben.

lg elundril


Delete - Sa 05.06.10 01:34

Richtig. Danke, für die Ergänzung. Ich glaube, dann hätten wir es jetzt zusammen.


Bergmann89 - Sa 05.06.10 01:59

Hey,

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
In diesem Fall bedeutet das const etwas anderes: der Parameter wird in der Funktion nicht verändert (aber intern als Referenz weitergegeben, was ressourcenschonender ist).
user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
const: by value, der Parameter wird als Kopie übergeben und kann nicht geändert werden.
Das steht jetz aber noch im Weiderspruch^^
also sllte es vlt so lauten: const: by Referenz, es wird ein Zeiger auf die Variable übergeben, aber der Speicherplatz darf nicht geschrieben werden.

MfG Bergmann


Delete - Sa 05.06.10 02:13

Wo ist bei den von dir zitierten Aussagen ein Widerspruch? Beide Aussagen beziehen sich auf unterschiedliche Dinge. Narses redet von const und ich von var. Das Delphi intern nur eine Referenz übergibt bei const, aus Optimierungsgründen, ändert nichts am Sachverhalt.


Bergmann89 - Sa 05.06.10 02:20

Hä? du hast doch ein von const gesprochen? Und wenn eine Referenz übergeben wird (auch wenns nur intern is), dann ist es doch nich mehr ByValue. Oder steh ich grad auf'm Schlauch?!^^


Delete - Sa 05.06.10 03:12

Richtig, dann ist es genau genommen nicht mehr by value. Aber du musst unterscheiden, was der Programmierer "sieht" und was Delphi intern macht. Für den Programmierer ist es by value für den Compiler by reference.


Bergmann89 - Sa 05.06.10 03:55

Ja, das meinte ich^^ Da hättmer ja jetz alles geklärt :)


SvenAbeln - Sa 05.06.10 11:17

user profile iconelundril hat folgendes geschrieben Zum zitierten Posting springen:
Gilt aber nur wenn die Variablen keine Objekte sind. In diesem Fall werden sie immer als Referenz übergeben.

Sorry, es wird aber doch kein Objekt direkt an eine Funktion übergeben, sondern eine Variable welche auf ein Objekt zeigt. Also gibt es auch in diesem Fall einen Unterschied zwischen by reference und by value.

Versuch dies mal ohne das VAR :wink:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure MakeObject(var AObject: TObject);
begin
  AObject:= TObject.Create;
end;


procedure TForm17.Button1Click(Sender: TObject);
var
  AObject: TObject;
begin
  AObject := NIL;
  MakeObject(AObject);
  if assigned(AObject) then
    ShowMessage('Object assigned')
  else
    ShowMessage('Object NOT assigned');
  AObject.Free;
end;


Delete - Sa 05.06.10 11:20

Nein, Zeiger ist Zeiger in diesem Fall. Nur Delphi lässt es nicht zu, dass du das Argument wieder zurück gibst, wenn du das Argument nicht als var deklarierst.


SvenAbeln - Sa 05.06.10 12:01

Das interessant ist aber doch wohin zeigt der Zeiger, direkt auf das Objekt oder auf eine Variable, die einen Zeiger auf ein Objekt enthält.

Delphi macht keine gesonderte Behandlung der Objekt Variablen, es wird auch dort genauso ein call by value oder by reference gemacht.
Dies kann man auch im Assembler sehen, im einen Fall wird der Wert übergeben (MOV) und im anderen die Adresse (LEA)


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure MakeObject(var AObject: TObject);
begin
  AObject:= TObject.Create;
end;

procedure MakeInteger(var AInteger: Integer);
begin
  AInteger := 5;
end;


Hier die Aufrufe mit Call by Value:

Quelltext
1:
2:
3:
4:
5:
6:
Unit17.pas.43: MakeObject(AObject);
004B331A 8B45F8           mov eax,[ebp-$08]
004B331D E8B2FFFFFF       call MakeObject
Unit17.pas.44: MakeInteger(AInteger);
004B3322 8B45F4           mov eax,[ebp-$0c]
004B3325 E8C6FFFFFF       call MakeInteger


Und hier als Call by Reference:

Quelltext
1:
2:
3:
4:
5:
6:
Unit17.pas.43: MakeObject(AObject);
004B3322 8D45F8           lea eax,[ebp-$08]
004B3325 E8AAFFFFFF       call MakeObject
Unit17.pas.44: MakeInteger(AInteger);
004B332A 8D45F4           lea eax,[ebp-$0c]
004B332D E8C2FFFFFF       call MakeInteger


fritz_07 - Di 08.06.10 23:12

Hallo an alle,

danke für die ausführlichen Erklärungen.

Ich hätte noch eine Zusatzfrage zu meinem Problem:
Also, der Vergleich über die Funktion ContainsText() funktioniert gut.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
var Inhalt, Suche : String,

begin

 Inhalt := Edit1.Text; //Inhalt bekommt den String z.B. Verzeichnis zugewisen
 Suche  := Edit2.Text; //In Suche steht jetzt aber der String z.B. Verzeichnisse

// durch den Vergleich würde es keine Fehlermeldung geben,da Verzeichnis in Verzeichnisse vorkommt.


Wie müßte ich die Funktion abändern,das nur nach dem Wort "Verzeichnis" gesucht wird,egal an welcher Stelle im Pfad das Wort steht.
Folglich, müßte dann beim Vergleich mit "Verzeichnisse" eine Fehlermeldung erscheinen,da dieses Wort ja länger ist.

Ich hoffe, ich konnte es einigermaßen beschreiben.


Gruß fritz_07


Lannes - Di 08.06.10 23:22

Hallo,

da in einem Pfad gesucht werden soll kannst du doch nach '\Verzeichnis\' suchen.


fritz_07 - Mi 09.06.10 22:40

Hallo Lannes,

deine Idee ist nicht schlecht,nur wenn '\Verzeichnis\' am Ende vom Pfad steht,fehlt der backslash.
Dann bekomme ich eine Fehlermeldung.

Würde sich diese Funktion besser eignen???


Delphi-Quelltext
1:
 function PosEx(SubStr: string, S: string, Offset: Integer): Integer;                    



Gruß fritz_07


Narses - Mi 09.06.10 22:54

Moin!

user profile iconfritz_07 hat folgendes geschrieben Zum zitierten Posting springen:
deine Idee ist nicht schlecht,nur wenn '\Verzeichnis\' am Ende vom Pfad steht,fehlt der backslash.
Dann pack doch zum Suchen temporär einen Backslash dran. :idea: :P

cu
Narses


fritz_07 - Sa 12.06.10 00:18

Hallo,

user profile iconNarses hat folgendes geschrieben:
Dann pack doch zum Suchen temporär einen Backslash dran.


Okay,habe ich gemacht.

Danke für eure Hilfe



Gruß fritz_07