Entwickler-Ecke
Sonstiges (Delphi) - worte zählen
Jenny - So 06.04.03 14:30
Titel: worte zählen
ich hab mal wieder ein kleines problem :mrgreen:
ich wollte eigentlich worte zählen aber delphi meckert an der stelle i:=1 rum :shock: anweisung für FOR schleifenvariable i
außerdem hab ich garnich verstanden warum ich da am ende
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
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:
| 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 - 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! :)
Jenny - So 06.04.03 15:27
naja... nich so das wahre wenn ich ehrlich bin :mrgreen: 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 :mrgreen:
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. - 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
Jenny - 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 :mrgreen:
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 - 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 :mrgreen:
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!
maximus - 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 :wink:
Jenny - So 06.04.03 16:03
@wulfskin: inc zählt immer einen dazu, ja... super... aber ich peil garnix mehr :cry: 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 :shock: :cry:
Christian S. - So 06.04.03 17:01
Hi!
Ich erkläre den Quelltext mal komplett und nicht nur die beiden Zeilen.
Zuerst wird geprüft, ob die Zeile leer ist.
Dann gehen wir an den Anfang der Zeile ...
... 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, ...
... speichern wir es in eine Variable, in die alle Zeichen kommen, die in irgendeinem Wort vorgekommen sind ...
... 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
Jenny - So 06.04.03 17:21
vielen vielen dank für deine mühe :)
jetzt hab ich das auch verstanden 8) nur auswendig kann ich es noch nich :mrgreen:
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. - 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.
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:
| 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
MSCH - 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:
http://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 - 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 :mrgreen:
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!