Autor Beitrag
Spansky
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 22

Win XP, Kubunto
Delphi 7
BeitragVerfasst: So 22.04.07 13:07 
Ich habe folgenden Algorithmus geschrieben. Er soll aus einem String alle Emailadressen herausfiltern und in eine Listbox schreiben. Allerdings funktioniert er nicht richtig. Es entsteht eine Zugriffsverletzung.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
procedure SucheEmailAdressen(str : string);
var i,j:integer;
Adresse : boolean; //Gibt an, ob es sich bei einem Wort um eine EmailAdresse handelt
var email : string;
begin
  i:=0;
  repeat
    begin
      if str[i]=' ' then //Leerzeichen sind das Signal für ein neues Wort
      begin
        adresse:=false;
        j:=i;//Notwendige Variable zur Einzelwortüberprüfung
        repeat //Schleife zum Untersuchen eines Wortes
          j:=j+1;
          email:=email+str[j];
          if str[j]='@' then adresse:=true; // wenn '@' im Wort => EmailAdresse
        until (str[j]=' 'or (j=length(str));// => Wortende bzw. Textende
        if adresse=true then Form2.ListBox1.AddItem(email,Form2.Listbox1); //Schreibe EmailAdresse in die Listbox
        email:='';//EmailAdresse zurücksetzen
        i:=j;//Einzelwortüberprüfung endet
        //i:=i+1;
      end;
      i:=i+1;
    end;
  until i=length(str);//Textende wurde erreicht
end;


Ich habs darauf hin mit ner anderen Lösung probiert:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
function StringIsEmail(str:string):boolean;//String = EmailAdresse???
var i:integer;
bed1,bed2:boolean;
begin
  result:=false;
  bed1:=false; bed2:=false;
  for i:=0 to length(str) do
  begin
    if str[i]='@' then bed1:=true;
    if str[i]='.' then bed2:=true;
    if bed1 and bed2 then result:=true
    else result:=false;
  end;
end;

function FindeWort(index:integer;str:string):string;//Filtert ein einzelnes Wort heraus. Der erste Buchstabe des Wortes liegt bei der Position index.
var i:integer;
begin
  i:=index;
  repeat
    result:=result+str[i];
    inc(i);
  until (i=length(str)) or (str[i]=' ');
end;

procedure FindEmailAdressen(str:string); //Letztendlicher Algorithmus mit Ausgabe
var i,p:integer;
begin
  i:=0;
  repeat
    p:=i;
    if StringIsEmail(FindeWort(p,str)) then Form2.ListBox1.AddItem(FindeWort(p,str),Form2.Listbox1);
    i:=i+length(FindeWort(p,str));
  until i=length(str);
end;


Auch hier entsteht wieder eine Schutzverletzung. Wo der Fehler liegt, ist mir ein Rätsel... vielleicht entdeckt ihr ihn ja. Ich hab Delphi 2005 PE benutzt.

Mfg,
Spansky
Dunkel
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 682

Mac OS X Snow Leopard
Xcode 3.1
BeitragVerfasst: So 22.04.07 13:23 
Was mir als Erstes aufgefallen ist: Strings fangen immer bei Index 1 an:

ausblenden Delphi-Quelltext
 
6:
7:
8:
9:
10:
{ ... }
  i:=1;
  repeat
    begin
      if str[i]=' ' then
...

_________________
Ich streite einsam mich mit dieser Oberflächenwelt
Gutes sei ein löblich Brot von dem ich zehre - bis zum Tod [Das Ich - Im Ich]
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 22.04.07 13:29 
Ferner solltest Du, wenn Du auf das Ende eines Strings prüfst i>=Length(Str) testen, da Du in deiner Schleife nicht explizit sicherstellen kannst, dass Du die Gleichheit je erreichen wirst. Erspart einem einiges an Debugging.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Spansky Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 22

Win XP, Kubunto
Delphi 7
BeitragVerfasst: So 22.04.07 13:41 
Super. Die Schutzverletzung ist schonmal weg. Allerdings wird bei dem folgenden Aufruf der Funktion nur das hier ausgegeben:



ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TForm2.Button1Click(Sender: TObject);
begin
  Listbox1.Items.Clear;
  //zw:=Clipboard.AsText;
  zw:='Hallo max.mustermann@test.de, wie geht es dir? Gruß frau.mustermann@test.de .';
  FindEmailAdressen(zw);
end;
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 22.04.07 13:43 
Kannst Du bitte kurz deinen aktuellen Source posten? Ich denk aber mal, dass Du nicht beachtet hast, dass beim Wegschneiden sich die Indizes im String verändern ;-)

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Spansky Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 22

Win XP, Kubunto
Delphi 7
BeitragVerfasst: So 22.04.07 14:13 
So hier is die Anwendung samt Source
Einloggen, um Attachments anzusehen!
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 22.04.07 14:30 
Kurz mal deinen Source überarbeitet ... ist aber ungetestet:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Clipbrd, ComCtrls ;

type
  TForm2 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form2: TForm2;
  zw:string;
implementation

{$R *.dfm}
function StringIsEmail(str:string):boolean; //String = EmailAdresse???
var i:integer;
bed1,bed2:boolean;
begin
  result:=false;
  bed1:=false;
  bed2:=false;
  for i:=1 to length(str) do
  begin
    if str[i]='@' then bed1:=true; //Sollte prüfen auf genau ein @-Zeichen
    if str[i]='.' then bed2:=true; //In einer Email-Adresse brauch theoretisch auch gar kein Punkt vorkommen. user@host ist genauso gültig ;-) Teste das einfach mal mit einem Linux deines Vertrauens :P
    if bed1 and bed2 then result:=true
    else result:=false;
  end;
end;

function FindeWort(index:integer;str:string):string;
var i:integer;
begin
  i:=index;
  result := '';
  while (i<=length(str)) and not (str[i] in [' '','':']) do
  begin
    result:=result+str[i];
    inc(i);
  end;
end;

procedure FindEmailAdressen(str:string);
var i,p:integer;
    s:String;
begin
  i:=0;
  repeat
    p:=i;
    s:=FindeWort(p,str);
    if StringIsEmail(s) then Form2.ListBox1.AddItem(FindeWort(p,str),Form2.Listbox1);
    i:=i+length(s)+1;
  until i>=length(str); //Eigentlich ja nur >, da aber ein Einzelzeichen keine gültige Email-Adresse darstellen kann, darf auf >= vereinfacht werden.
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
  Listbox1.Items.Clear;
  //zw:=Clipboard.AsText;
  zw:='Hallo max.mustermann@test.de, wie geht es dir? Gruß frau.mustermann@test.de .';
  FindEmailAdressen(zw);
end;

end.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Spansky Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 22

Win XP, Kubunto
Delphi 7
BeitragVerfasst: So 22.04.07 15:00 
ok... funzt alles super. Die Unit wird jetzt noch nen bisschen weiterentwickelt und demnächst als Open-Source-Unit veröffentlicht. Danke für deine Hilfe, BenBE.