Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Anzahl eines Zeichen in einem String ermitteln


XooL - Sa 13.01.07 16:59
Titel: Anzahl eines Zeichen in einem String ermitteln
Hi,

ich habe zur Zeit ein kleines Problem und zwar:
ich möchte einen String nach einem bestimmten Zeichen durchsuchen (z.B. '#') und einer Integervariablen übermitteln wir oft dieses Zeichen enthalten ist.
Hat jemand ne Idee ?

greez XooL


jaenicke - Sa 13.01.07 17:10

http://www.swissdelphicenter.ch/en/showcode.php?id=1326
Die erste Funktion macht etwas ähnliches, sie zerlegt einen String anhand eines Trennzeichens. Ich denke mal, du siehst daran, wie du das machen musst.
Das Array als ersten Parameter brauchst du ja gar nicht, weil du die einzelnen Teile des Strings nicht brauchst.

Alternativ (das wäre schneller) könntest du auch mit PosEx durch den String gehen. PosEx sucht ab einer bestimmten Position nach einem String in einem String, du kannst also hinter dem zuletzt gefundenen Zeichen weitersuchen.


XooL - Sa 13.01.07 17:23

Die Möglickeit mit PosEx scheidet aus, da dies in Delphi6 nicht vorhanden ist :( ... trotzdem danke


Dunkel - Sa 13.01.07 17:31

user profile iconXooL hat folgendes geschrieben:
Die Möglickeit mit PosEx scheidet aus, da dies in Delphi6 nicht vorhanden ist :( ... trotzdem danke

Hast Du auch folgendes gemacht?

Delphi-Quelltext
1:
2:
uses
..., StrUtils ,...


jaenicke - Sa 13.01.07 17:50

Nein, er hat schon Recht, PosEx gibts erst ab Delphi 7. Hätte im Profil die Delphi-Version gestanden, hätte ich es auch gar nicht erwähnt... ;-)

Aber mit Delete in der Schleife wie in dem verlinkten Beispiel gehts ja...


XooL - Sa 13.01.07 20:42

ich hab mal was ausprobiert, aber es funktioniert noch nicht ganz einwandfrei, vllt. sieht ja einer von euch meinen fehler:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
while x = false do
begin
if pos('#',l)=0 then         //wenn er nichts findet ist der Wert=0
                 begin
                  x:=true;
                 end
                else
                 begin
                  zahl:=zahl+1;
                  Delete(l,0, pos('#',l));
                  if length(l)=0 then x:=true;
                 end;
end;


Moderiert von user profile iconChristian S.: Code- durch Delphi-Tags ersetzt


jaenicke - Sa 13.01.07 21:03

Erstens: Ich rate dringend von einem l als String-Variablen ab... Man verwechselt das leicht mit einer 1...
(Jedenfalls in der Quelltextformatierung ;-))
Außerdem: Warum rückst du erst so viel und dann fast gar nicht ein? Das macht es sehr unübersichtlich...

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
zahl := 0// wichtig! erst initialisieren!
while not x do // nicht x, also x = false ;-)
begin 
  if pos('#', l) = 0 then //wenn er nichts findet ist der Wert=0
  begin 
    x := true; 
  end 
  else 
  begin 
    zahl := zahl + 1;
    Delete(l, 1, Pos('#', l)); // Wenn du von Null aus löschst, dann ist das falsch (s.u.)
    if Length(l) = 0 then 
      x := true; 
  end
end;

Das erste Zeichen in einem String hat den Index 1. So löschst du also ein Zeichen zu wenig. (Vorausgesetzt es gibt keinen Fehler, aber das hättest du ja sicherlich dazugesagt.)
Das übrigbleibende Zeichen ist? Richtig, das Trennzeichen, also die Raute!
Naja, also bleibt es vor dem ersten hängen --> Endlosschleife...

Hier eine andere Version:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
zahl := 0// wichtig! erst initialisieren!
while (Length(l) > 0and (Pos('#', l) > 0do 
  // Solange noch eine Raute gefunden wird und noch was in l drin ist
begin
  Inc(zahl); // Inkrementiert zahl, also erhöht zahl um eins
  Delete(l, 1, Pos('#', l)); // Wenn du von Null aus löschst, dann ist das falsch (s.u.)
end;

Beides ist ungetestet, sollte aber gehen...


Stinger47 - Sa 13.01.07 22:48

ich weiß nicht ob das problem schon gelöst ist aber ich hätte es eher so gelöst...


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
var
  Wort    :  String;    // da kommt halt der zu untersuchende string rein...
  Anzahl  :  Integer;   // die anzahl des zeichens...
  i       :  Integer;   // laufvariable für die schleife
  
begin

 anzahl  :=  0

 for i := 1 to length(wort) do                      // hier wir geschaut wie lang der string ist und dann jedes einzelne zeichen überprüft
   begin
     if (wort[i] = 'e'or (wort[i] = 'E'then     // wenn das i-te zeichen ein e ist (du kannst auch ne variable machen und dann halt nach dem zeichen
       anzahl  :=  anzahl + 1;                      // suchen was du möchtest) dann soll anzahl um einen erhöht werden....wichtig ist das du bei buchstaben
   end;                                             // zwischen groß und kleinbuchstaben differenzierst...die zahl kannste dann ja in nem label ausgeben oder
                                                    // so


wenn du diese zeichen noch löschen möchtest die gefunden worden sind solltest du die schleife rückwärts zählen lassen, so dass er von hinten anfängt zu untersuchen und dann kannste die löschen sonst kann es sein das du ein zeichen auslässt da das nächste zeichen ja an die position des gelöschten ziechens rückt...
hoffe konnte dir helfen...:)


Lannes - So 14.01.07 00:48

Hallo,

dafür:

Delphi-Quelltext
1:
if (wort[i] = 'e'or (wort[i] = 'E'then                    

würde ich das nehmen:

Delphi-Quelltext
1:
if UpCase(wort[i]) = UpCase('a'then                    


Xion - So 14.01.07 13:07

hier, ich habs mal schnell gecodet:


CountLetter
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
function CountLetter(Word: String; Letter: Char): integer; 
//wenn du auch mehrere Buchstaben suchen  
//willst (also z.B. "Blub") dann musst aus dem Char einfach String machen
begin
 Word:=AnsiLowerCase(Word); //AnsiLowerCase funzt auch bei Ä usw.
 Letter:=AnsiLowerCase(Letter);
 Result:=0;
 
 if Letter<>'' then
   while Pos(Letter,Word)>0 do
     begin
       Result:=Result+1;
       Delete(Word,1,Pos(Letter,Word)+Length(Letter));
     end;
end;



XION


Delete - So 14.01.07 14:05

Die Version mit dem Index ist auf alle Fälle vorzuziehen, da Zeichenkettenoperationen nicht sehr performant sind, da immer wieder Seicher alloziiert werden muss und die Zeichenkette umkopiert wird.