Autor Beitrag
Jenny
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 35



BeitragVerfasst: So 06.04.03 14:30 
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
ausblenden Quelltext
1:
2:
inc(i);
 ch:=txt[i];


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



ausblenden volle Höhe 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 896

Win XP, Suse 8.1
Delphi 4/7/8 alles prof
BeitragVerfasst: 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:
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 35



BeitragVerfasst: 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.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: 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:

ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 35



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: 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!

_________________
Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
maximus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 896

Win XP, Suse 8.1
Delphi 4/7/8 alles prof
BeitragVerfasst: So 06.04.03 15:56 
@Jenny: wusste nicht, das du an den code gebunden bist*g*

Aber sonst würde dies gehn:
ausblenden 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:

_________________
mfg.
mâximôv
Jenny Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 35



BeitragVerfasst: 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.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: So 06.04.03 17:01 
Hi!

Ich erkläre den Quelltext mal komplett und nicht nur die beiden Zeilen.

ausblenden Quelltext
1:
if txt<>'' then					

Zuerst wird geprüft, ob die Zeile leer ist.
ausblenden Quelltext
1:
      k:=1;					

Dann gehen wir an den Anfang der Zeile ...
ausblenden Quelltext
1:
      ch:=txt[k];					

... und speichern das Zeichen an dieser Stelle.
ausblenden Quelltext
1:
      while k<= length(txt) do					

Solange wir das Ende der Zeile nicht erreicht haben, machen wir folgendes:
ausblenden Quelltext
1:
      if KleinInGross(ch) in buchstaben					

Wenn das in "ch" gespeicherte Zeichen ein Buchstabe ist, dann ...
ausblenden 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:
ausblenden Quelltext
1:
2:
        while KleinInGross(ch) in buchstaben do
        begin

Solange das gespeicherte Zeichen ein Buchstabe ist, ...
ausblenden Quelltext
1:
          wort:=wort+ch;					

... speichern wir es in eine Variable, in die alle Zeichen kommen, die in irgendeinem Wort vorgekommen sind ...
ausblenden Quelltext
1:
2:
          inc(k);
          ch:=txt[k];

... 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:
ausblenden 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:
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 35



BeitragVerfasst: 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.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: 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.

ausblenden volle Höhe 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

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
MSCH
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1448
Erhaltene Danke: 3

W7 64
XE2, SQL, DevExpress, DevArt, Oracle, SQLServer
BeitragVerfasst: So 06.04.03 17:55 
ich hab hier was :

ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 35



BeitragVerfasst: 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: