Für mich ist keine der bisher gezeigten Versionen überzeugend.
In #1 des TE werden alle Zeichen, die keine Alphazeichen sind als Zeichen eines Wortes angesehen.
In #4 werden immerhin Steuerzeichen und ein paar Interpunktionszeichen als nicht zu Worten gehörend angesehen, was auch nicht wirklich Sinn macht.
Nehmen wir den SourceCode des Autors dieses Beitrags als Beispiel, dann sehen wir auf Anhieb ein Dutzend weitere Zeichen, die offensichtlich in Texten vorkommen aber nicht zu Worten gehören.
Auch die Modifikation "2.UInt64 statt Integer für Strings > 2GiB (sicher ist sicher)" ist überflüssig, denn ein String mag > 2GiB sein, aber die Länge (Anzahl Zeichen) liegt innerhalb des Integerbereiches.
Der Autor selbst läuft ja mit
for I := Low(Text) to High(Text) do
durch den Text, wobei I als Integer deklariert ist.
Hier wird deutlich, dass als Integer deklarierte Zähler für Zeichen und Worte unter keinen Umständen "überlaufen" können.
Hier ist mein Vorschlag in dem die in der Windows
API deklarierte Funktion "IsCharAlpha" benutzt wird um zu Worten gehörende Zeichen zu erkennen.
Auch das ist sicher nicht optimal, denn je nach Definition des Begriffs "Wort" kann diese Prüfung unvollständig sein.
Delphi-Quellcode:
type
TFileMetrics=Record
Chars:Integer;
AlphaChars:Integer;
ControlChars:Integer;
Words:Integer;
AvgWordLen:Single;
End;
FUNCTION GetFileMetrics(Dsn:
String):TFileMetrics;
var List:TStrings; S:
String; P,P1:PChar;
begin
FillChar(Result,SizeOf(Result),0);
List:=TStringList.Create;
try
try
List.LoadFromFile(Dsn);
S:=List.Text;
if S='
'
then Exit;
P:=PChar(S);
Result.Chars:=Length(S);
while P^<>#0
do
if IsCharAlpha(P^)
then begin
P1:=P;
while IsCharAlpha(P^)
do Inc(P);
Inc(Result.AlphaChars,P-P1);
Inc(Result.Words);
end else begin
if P^<#32
then Inc(Result.ControlChars);
Inc(P);
end;
if Result.Words>0
then Result.AvgWordLen:=Result.AlphaChars/Result.Words;
except
on E:
Exception do ShowMessage(E.
Message);
end;
finally
List.Free;
end;
end;
PROCEDURE TMain.Test;
begin
if OpenDialog.Execute
then
with GetFileMetrics(OpenDialog.FileName)
do
ShowMessage('
Worte '+IntToStr(Words)+#13+
'
Avg Länge '+FloatToStr(AvgWordLen)+#13+
'
Zeichen '+IntToStr(Chars)+#13+'
Davon:'+#13+
'
- Kontroll Zeichen '+IntToStr(ControlChars)+#13+
'
- Alpha Zeichen '+IntToStr(AlphaChars)+#13+
'
- Non Alpha Zeichen '+IntToStr(Chars-AlphaChars-ControlChars));
end;