Autor |
Beitrag |
Jenny
      
Beiträge: 35
|
Verfasst: So 06.04.03 14:30
ich hab mal wieder ein kleines problem
ich wollte eigentlich worte zählen aber delphi meckert an der stelle i:=1 rum  anweisung für FOR schleifenvariable i
außerdem hab ich garnich verstanden warum ich da am ende
Quelltext
hingeschrieben hab *g*
und ich weiss auch nich ob das so schon alles is und er die worte zählen kann... wär schön wenn ihr mir helfen könntet
dankesehr
Jenny
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:
| function KleinInGross(c:char):char; begin case c of 'ä': KleinInGross:='Ä'; 'ö': KleinInGross:='Ö'; 'ü': KleinInGross:='Ü'; else KleinInGross:=Upcase(c) end; end;
procedure TForm1.Memo1Change(Sender: TObject); var i,anz_worte:integer; txt, wort:string; ch:char; const buchstaben=['A'..'Z'];
begin anz_worte:=0; txt:=Memo1.text; for i:=1 to Memo1.lines.count-1 do begin txt:=trim(Memo1.lines[i]); if txt<>'' then begin i:=1; // hier meckert er rum ch:=txt[i]; while i<= length(txt) do if KleinInGross(ch) in buchstaben then begin inc(anz_worte); while KleinInGross(ch) in buchstaben do begin wort:=wort+ch; inc(i); ch:=txt[i]; end; end; end; end; l_worte.caption:=IntToStr(anz_worte); end; |
|
|
maximus
      
Beiträge: 896
Win XP, Suse 8.1
Delphi 4/7/8 alles prof
|
Verfasst: So 06.04.03 15:19
Hilo...
dein 'i' prob liegt daran, dass du das i schon in der for-schleife verwendest und for-zähler dürfen nu'mal nich manipuliert werden( das war auch mal anders...früher).
Ich würd von einer anderen seite an das wörter-zählen ranngehen:
Ich untersuche nicht die wörter, sondern die zwischen räume: Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| Function Wordcount(s:string):integer; const wDelimiter = [' ',':','.',',','!','?','-',#$D,#$A,#9]; // kann noch ergänzt werden var run,len:integer; begin run := 1; result := 0; len := length(s); repeat while s[run] in wDelimiter do inc(run); if run>len then exit; inc(result); While not (s[run] in wDelimiter) do inc(run); until run>len; end; |
...ich denke das könnte gehen! 
_________________ mfg.
mâximôv
|
|
Jenny 
      
Beiträge: 35
|
Verfasst: So 06.04.03 15:27
naja... nich so das wahre wenn ich ehrlich bin  ich kann ja schlecht alle möglichen zeichen in der konstanten eintragen... da bin ich ja noch nich fertig wenn ich alt und grau bin
und außerdem kann ich nich plötzlich mit was ganz neuem antanzen in der klausur morgen...
weisst du zufällig wie man das mit dem i umgehen kann?
trotzdem danke für deine hilfe 
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: So 06.04.03 15:43
Hi!
Also, erstmal solltest Du die FOR-Schleife bei Null beginnen lassen, denn die erste Zeile im Memo hat den Index 0.
Das mit dem i löst Du ganz einfach dadurch, dass Du ab "if txt<>'' ..." statt einem i eine andere Variable verwendest. Also so:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| if txt<>'' then begin k:=1; ch:=txt[k]; while k<= length(txt) do if KleinInGross(ch) in buchstaben then begin inc(anz_worte); while KleinInGross(ch) in buchstaben do begin wort:=wort+ch; inc(k); ch:=txt[k]; end; end; end; |
Allerdings glaube ich nicht, dass das so funktioniert. Du musst k auch noch erhöhen wenn "ch" nicht in "buchstaben" enthalten ist, sonst hängt er in der "while k<= length(txt)"-Scheife fest!
MfG,
Peter
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
Jenny 
      
Beiträge: 35
|
Verfasst: So 06.04.03 15:48
danke peter
aber kannst du mir meine letzten beiden zeilen erklären? die mit dem
inc(k) etc. die hab ich nämlich selbs nich geschnallt
und wie mach ich das das k weiter erhöht wird? das ende von dem ganzen da scheint mir irgendwie so abgebrochen... ich steig da nich durch 
|
|
wulfskin
      
Beiträge: 1349
Erhaltene Danke: 1
Win XP
D5 Pers (SSL), D2005 Pro, C, C#
|
Verfasst: So 06.04.03 15:51
Jenny hat folgendes geschrieben: | aber kannst du mir meine letzten beiden zeilen erklären? die mit dem
inc(k) etc. die hab ich nämlich selbs nich geschnallt
und wie mach ich das das k weiter erhöht wird? |
Du beantwortest dir deine Frage hier selber: Inc erhöht k  !
Am besten du schaust die Inc mal in der Hilfe an!
Gruß wulfskin!
_________________ Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
|
|
maximus
      
Beiträge: 896
Win XP, Suse 8.1
Delphi 4/7/8 alles prof
|
Verfasst: So 06.04.03 15:56
@Jenny: wusste nicht, das du an den code gebunden bist*g*
Aber sonst würde dies gehn:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| Function Wordcount(s:string):integer; const validChars = ['a'..'z','A'..'Z','0'..'9','ä','ü','ö','Ä','Ü','Ö']; var run,len:integer; begin run := 1; result := 0; len := length(s); repeat while (run<=len) and not (s[run] in validChars) do inc(run); if run>len then exit; inc(result); While (run<=len) and (s[run] in validChars) do inc(run); until run>len; end; |
Also doch die wörte analysieren...is wohl die bessere idee 
_________________ mfg.
mâximôv
|
|
Jenny 
      
Beiträge: 35
|
Verfasst: So 06.04.03 16:03
@wulfskin: inc zählt immer einen dazu, ja... super... aber ich peil garnix mehr  was hat das in der blöden while schleife zu suchen?
außerdem stand das oben schonmal das ch:=txt[k]
@maximus: lieb das du dir sone mühe machst  das scheint auch ganz vernünftig auszusehen... aber ich krig hier bald ne kriese! ich kann nich ständig irgendwas neues in meinen schädel reinhaun der platzt gleich 
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: So 06.04.03 17:01
Hi!
Ich erkläre den Quelltext mal komplett und nicht nur die beiden Zeilen.
Quelltext
Zuerst wird geprüft, ob die Zeile leer ist.
Quelltext
Dann gehen wir an den Anfang der Zeile ...
Quelltext
... und speichern das Zeichen an dieser Stelle.
Quelltext 1:
| while k<= length(txt) do |
Solange wir das Ende der Zeile nicht erreicht haben, machen wir folgendes:
Quelltext 1:
| if KleinInGross(ch) in buchstaben |
Wenn das in "ch" gespeicherte Zeichen ein Buchstabe ist, dann ...
Quelltext 1: 2:
| then begin inc(anz_worte); |
... fängt dort ein Wort an. Wir können uns nicht innerhalb eines Wortes befinden, weil wir nur an diese Stelle gelangen, wenn vorher mal ein Zeichen da war, welches kein Buchstabe war. Das bewirkt die folgende Schleife:
Quelltext 1: 2:
| while KleinInGross(ch) in buchstaben do begin |
Solange das gespeicherte Zeichen ein Buchstabe ist, ...
Quelltext
... speichern wir es in eine Variable, in die alle Zeichen kommen, die in irgendeinem Wort vorgekommen sind ...
Quelltext
... und gehen zum nächsten Zeichen und speichern es in "ch". Mit diesem "neu" gespeicherten Zeichen durchlaufen wir die Schleife wieder, speichern wieder das nächste Zeichen, solange, bis das Zeichen kein Buchstabe mehr ist: das Wort hat aufgehört.
So, und nun zu dem, was da noch fehlt.
Wir gucken uns noch einmal diese Zeile an:
Quelltext 1:
| if KleinInGross(ch) in buchstaben |
Wenn "ch" ein Buchstabe ist, dann verändern wir die aktuelle Position, die wir uns anschauen, weil wir durch ein Wort durchgehen. Wir müssen aber auch dafür sorgen, dass wir weitergehen, wenn es kein Buchstabe ist. Das schreit nach einem "sonst" oder "else".
Also so:
Quelltext 1: 2: 3: 4:
| if KleinInGross(ch) in buchstaben then begin {...} end else inc(k); |
Ohne Gewähr, aber so müsste es funktionieren.
MfG,
Peter
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
Jenny 
      
Beiträge: 35
|
Verfasst: So 06.04.03 17:21
vielen vielen dank für deine mühe
jetzt hab ich das auch verstanden  nur auswendig kann ich es noch nich
ich weiss aber nicht ob das nu funktioniert weil delphi rumspinnt... der quelltext is okay da motzt er nich mehr aber wenn ich das programm starte kann man plötzlich nix mehr machen... weder schreiben noch die maus auf das fenster bewegen 
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: So 06.04.03 17:41
Das hängen kommt daher, dass Du wahrscheinlich meine letzte Änderung noch im umgesezt hast. Die war sowieso unvollständig, wie ich jetzt bemerkt habe.
Folgenden Quelltext habe ich gerade mal ausprobiert und er scheint zu funktionieren.
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:
| procedure TForm1.Memo1Change(Sender: TObject); var i, k, anz_worte : Integer; txt, wort:string; ch:char; const buchstaben=['A'..'Z'];
begin anz_worte:=0; txt:=Memo1.text; for i:=0 to Memo1.lines.count-1 do begin txt:=trim(Memo1.lines[i]); if txt<>'' then begin k:=1; ch:=txt[k]; while k<= length(txt) do if KleinInGross(ch) in buchstaben then begin inc(anz_worte); while KleinInGross(ch) in buchstaben do begin wort:=wort+ch; inc(k); ch:=txt[k]; end; end else //<-- begin //<-- inc(k); //<-- if k <=length(txt) then ch:=txt[k]; //<-- end; //<-- end; end; l_worte.caption:=IntToStr(anz_worte); end; |
Der Fehler, den ich bei besagter Änderung behoben habe: wir müssen nicht nur k erhöhen, sondern auch das entsprechende Zeichen in "ch" speichern, sonst prüfen wir ja immer das Zeichen, welches als letztes in einem Wort enthalten war. Ich habe die Änderung im Quelltext markiert.
Auch wenn Du keine neue Funktion lernen möchtest, hier noch ein Hinweis: es ist irgendwie Unsinn, bei jedem Tastendruck die Anzahl der Wörter von Neuem zu berechnen. Viel sinnvoller wäre es, die Anzahl der Wörter global zu speichern und nur die Veränderung Der Wortanzahl zu berechnen.
MfG,
Peter
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
MSCH
      
Beiträge: 1448
Erhaltene Danke: 3
W7 64
XE2, SQL, DevExpress, DevArt, Oracle, SQLServer
|
Verfasst: So 06.04.03 17:55
ich hab hier was :
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| const gcWordDelims = [#1..#47,#58..#64,#91..#96,#123..#126]-['`'];
function TStringManager.ExtractWords(const s : String; const aList : TStrings = nil; const Delims : TCharSet = gcWordDelims) : TStrings; var i : Integer; j : Integer; SLen : Integer; begin if aList=nil then Result := TStringList.Create else Result := aList; SLen := Length(s); i := 1; while i<=SLen do begin while (i<=SLen) and (s[i] in Delims) do Inc(i); j := i; while (i<=SLen) and (not (s[i] in Delims)) do Inc(i); if i-j>0 then Result.Add(System.Copy(s, j, i-j)); end; end; |
Quelle: TStringManager
Class with string functions - by Eric Grobler (egrobler@quoka.com)
Status: Freeware - No restrictions apply - without a warranty of any kind.
(This library is based on my previous badly named TStringCollection class)
Compiler: Delphi4, Delphi5, Delphi6
Version: 2.4b
Lastdate: 27 Jan 2002
Url: www.geocities.com/ericdelphi/StrMan.html
This library does not support multibyte (MBCS) strings (Japanese, Chinese, etc).
(Note that most Delphi string functions does not support MBCS either)
It does however support European Ansi case characters.
Please report any bugs, suggestions to egrobler@quoka.com
grez
msch
|
|
Jenny 
      
Beiträge: 35
|
Verfasst: So 06.04.03 18:36
vielen dank peter, es funktioniert jetzt endlich
sicher gibt es bessere wege aber für die klausur morgen mach ich das nich... wenn ich privat was progge nehm ich gerne bessere vorschläge an
@MSCH: danke für deine hilfe  aber wie gesagt ist das problem behoben  und in deinem code sind n paar sachen die wir noch nich hatten 
|
|
|