Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   String-Ende mit while finden (https://www.delphipraxis.net/205210-string-ende-mit-while-finden.html)

Caps 12. Aug 2020 13:26

String-Ende mit while finden
 
Hallo,

ich glaube ich stehe auf dem Schlauch.
Ich habe nirgends Infos gefunden, womit ein AnsiString nun terminiert wird, oder wo die Länge zu finden ist.
Ich würde gern einen String Byte für Byte durchlaufen, aber mit while, bis ich das Ende erreicht habe.

Die Frage ist nun, wie ich erkenne, dass ich das Ende erreicht habe(?).

Ich möchte nicht zuerst die Länge abfragen und dann den Laufindex damit vergleichen, sondern ich möchte eine Bedingung wissen, wie ich das Ende erkennen kann. Gibt es sowas?

lg Caps

KodeZwerg 12. Aug 2020 13:32

AW: String-Ende mit while finden
 
Delphi-Quellcode:
for i := 0 to 65535 do
  if ansistr[i] = AnsiChar(#0) then
    begin
      break;
    end;
so was?

matashen 12. Aug 2020 13:32

AW: String-Ende mit while finden
 
Hallo,

wie wärs mit

length(deinString)


Delphi-Quellcode:
var I:Integer

for i:=1 to length(deinString) do irgendwas
order bei neurem Delphi

deinstring.length

EDIT: geht nicht mit AnsiString


Gruß Matthias

matashen 12. Aug 2020 13:34

AW: String-Ende mit while finden
 
Zitat:

Zitat von KodeZwerg (Beitrag 1471679)
Delphi-Quellcode:
for i := 0 to 65535 do
  if ansistr[i] = AnsiChar(#0) then
    begin
      break;
    end;
so was?

laut Delphi Wiki
http://docwiki.embarcadero.com/Libra...tem.AnsiString
"Die Indizierung von AnsiString beginnt bei 1"

Caps 12. Aug 2020 13:36

AW: String-Ende mit while finden
 
Ich würde das gerne mit while erreichen.
Ich müsste bloß wissen, wie die Bedingung für das Ende lautet.

Kann es sein, dass lange Strings doch mit #0 terminiert sind?
Gilt dann mein_string [length(mein_string)+1] = #0? Oder gibt es da einen Zugriffsfehler?

lg Caps

Caps 12. Aug 2020 13:37

AW: String-Ende mit while finden
 
Zitat:

Zitat von matashen (Beitrag 1471681)
Zitat:

Zitat von KodeZwerg (Beitrag 1471679)
Delphi-Quellcode:
for i := 0 to 65535 do
  if ansistr[i] = AnsiChar(#0) then
    begin
      break;
    end;
so was?

laut Delphi Wiki
http://docwiki.embarcadero.com/Libra...tem.AnsiString
"Die Indizierung von AnsiString beginnt bei 1"

Ah, Du prüfst mit #0, ok.
Nur die Länge 65535 ist zu kurz. Meine Strings sind wesentlich länger.

KodeZwerg 12. Aug 2020 13:37

AW: String-Ende mit while finden
 
Delphi-Quellcode:
while AnsiStr[i] <> AnsiChar(#0) do


sorry wg falschem start index vorhin.

matashen 12. Aug 2020 13:38

AW: String-Ende mit while finden
 
Zitat:

Zitat von Caps (Beitrag 1471683)
Zitat:

Zitat von matashen (Beitrag 1471681)
Zitat:

Zitat von KodeZwerg (Beitrag 1471679)
Delphi-Quellcode:
for i := 0 to 65535 do
  if ansistr[i] = AnsiChar(#0) then
    begin
      break;
    end;
so was?

laut Delphi Wiki
http://docwiki.embarcadero.com/Libra...tem.AnsiString
"Die Indizierung von AnsiString beginnt bei 1"

Ah, Du prüfst mit #0, ok.
Nur die Länge 65535 ist zu kurz. Meine Strings sind wesentlich länger.

Dann nimm halt Length(ansistr)

Caps 12. Aug 2020 13:39

AW: String-Ende mit while finden
 
Ok, danke, ich probiere das mit #0.
Das war die Information, die sich in der Delphi-Hilfe ein wenig versteckt ^^.

Danke und Grüße!
Caps

matashen 12. Aug 2020 13:39

AW: String-Ende mit while finden
 
Delphi-Quellcode:
i:=0
while i<length(ansistr) do
begin;
 inc(i);
tu irgendwas mit deinem String
end;

KodeZwerg 12. Aug 2020 13:42

AW: String-Ende mit while finden
 
Zitat:

Zitat von Caps (Beitrag 1471686)
Ok, danke, ich probiere das mit #0.
Das war die Information, die sich in der Delphi-Hilfe ein wenig versteckt ^^.

Danke und Grüße!
Caps

gerne, allerdings gilt das mit #0 nur bei text strings. wenn dein ansistring binär ist klappt das alles nicht.

Caps 12. Aug 2020 13:44

AW: String-Ende mit while finden
 
Genau, es ist nur Text.
Und den Aufruf von length wollte ich vermeiden.

Wenn lange Strings max. 2GB lang sein können, müsste LongWord als Typ für die Länge reichen, oder?
Das war meine anfängliche Sorge...

KodeZwerg 12. Aug 2020 13:45

AW: String-Ende mit while finden
 
LongWord/Cardinal wäre passend.

himitsu 12. Aug 2020 13:49

AW: String-Ende mit while finden
 
ShortString (der erste Delphi-String hat im Char [0] sein LängenByte)

LongString im Delphi (String, bzw. AnsiString und Nachfahren ala UTF8String, sowie UnicodeString) und auch der WideString (Interne Weiterleitung zur MSDN-Library durchsuchenSysAllocString-API)
gibt es einen Integer vor den Chars (ein Record im negativen Index, mich Length, CodePage, RefereceCount und CharSize)
Und nach dem letzten Char gibt es noch implizit zwei #0.

#0 als StringEnde wird implitzt für "einfache" Castas zu PChar untersützt, aber der String selber reagiert ausschließlich auf die Längenangabe.


Man kann nach PChar casten und APIs ala MSDN-Library durchsuchenStrEnd benutzen.
Oder wenn man einfach nur abschneiden will, dann die impliziten String-Funktionen für PChar->String nutzen.
Delphi-Quellcode:
S := PChar(S);



Zitat:

LongWord/LongInt/Integer
Delphi verwendet überall Integer (LongInt) als Länge und Index.

Leider auch dann, wenn man für 64 Bit kompiliert. (k.A. warum hier jemand auf diese saudämliche Idee gekommen ist)
Ansonsten wäre NativeInt der passende Typ gewesen. :cry:
Denn intern ist String eigentlich nur ein aufgemotztes dynamische Array und dessen Length ist als NativeInt deklariert, womit unter 64 Bit diese Typen nicht mehr kompatibel sind. :wall:

TiGü 12. Aug 2020 13:49

AW: String-Ende mit while finden
 
Zitat:

Zitat von Caps (Beitrag 1471690)
Genau, es ist nur Text.
Und den Aufruf von length wollte ich vermeiden.

Warum? Akademisches Interesse?

Caps 12. Aug 2020 13:51

AW: String-Ende mit while finden
 
"[...] aber der String selber reagiert ausschließlich auf die Längenangabe [...]"

Aber ich kann doch das while-Konstrukt mit dem Vergleich auf #0 benutzen, oder?
Es gibt keinen Zugriffsfehler am Ende?

Caps 12. Aug 2020 13:51

AW: String-Ende mit while finden
 
Zitat:

Zitat von TiGü (Beitrag 1471693)
Zitat:

Zitat von Caps (Beitrag 1471690)
Genau, es ist nur Text.
Und den Aufruf von length wollte ich vermeiden.

Warum? Akademisches Interesse?

Ja ^^

KodeZwerg 12. Aug 2020 13:53

AW: String-Ende mit while finden
 
Zitat:

Zitat von TiGü (Beitrag 1471693)
Zitat:

Zitat von Caps (Beitrag 1471690)
Genau, es ist nur Text.
Und den Aufruf von length wollte ich vermeiden.

Warum? Akademisches Interesse?

hmm ich grübel gerade, eigentlich sollten es zwei unterschiedliche ergebnisse haben.
"Length(Text)" und "While not #0 inc(i)"
Length liefert länge vom text, incremental count liefer zusätzlich auch alles nicht-sichtbare.
Beispiel Zeilenumbrüche = 2 bytes

Caps 12. Aug 2020 13:54

AW: String-Ende mit while finden
 
Length liefert NICHT die Zeilenumbrüche mit?
Das würde mich jetzt aber aus der Bahn werfen...

himitsu 12. Aug 2020 13:59

AW: String-Ende mit while finden
 
Zitat:

Zitat von Caps (Beitrag 1471694)
Es gibt keinen Zugriffsfehler am Ende?

Wenn du über den String zugreifst, dann mußt du neben #0 auch Length beachten, denn wenn kein #0 im String vorkommt, kommt es bei aktiver Indexprüfung zu einem Fehler.
Über einen Cast nach PChar kannst du auch "sicher" zwei 2 Zeichen hinter das String-Ende zugreifen.

Ein Leer-String ist eigentlich NIL, aber Delphi-Referenz durchsuchenPChar(S) leitet bei '' auf eine "Ersatz"-Konstante um welche aus #0#0 besteht, womit es dann immer ein #0 als Ende gibt. (außer jemand hat über einen BufferOverflow dieses zerschossen)


PS: Zwei #0 als Ende, weil es im Windows auch ein Art StringList / Array gibt, wo Strings per #0 getrennt sind und das Ende der Liste als #0#0 definiert ist (also ein leerer String '' ist das Ende)
Und zusällig wird dieses auch in der Delphi-RTTI verwendet, z.B. für die Namen in Enums. (weswegen man hier auch keine RTTI für Enums bekommt, wo Werte übersprungen werden :cry:)

Caps 12. Aug 2020 14:01

AW: String-Ende mit while finden
 
Ok, dann werde ich vorher auf PChar casten, danke.

himitsu 12. Aug 2020 14:06

AW: String-Ende mit while finden
 
Die Hilfe schreibt inzwischen auch mal mehr zu den früher geheimen Internas.
http://docwiki.embarcadero.com/RADSt...Typen_(Delphi)

Und der geheime Typ StrRec in der System.pas

Caps 12. Aug 2020 14:08

AW: String-Ende mit while finden
 
Danke :)

lg Caps

KodeZwerg 12. Aug 2020 14:18

AW: String-Ende mit while finden
 
Zitat:

Zitat von himitsu (Beitrag 1471701)
Die Hilfe schreibt inzwischen auch mal mehr zu den früher geheimen Internas.
http://docwiki.embarcadero.com/RADSt...Typen_(Delphi)

Und der geheime Typ StrRec in der System.pas

*Knuddel* auf Dich ist immer verlass *Knuddel*

KodeZwerg 12. Aug 2020 14:28

AW: String-Ende mit while finden
 
für akademische zwecke, hier noch ein kurzer link aus dem Jahr 2009/2011.

Delphi.Narium 12. Aug 2020 14:51

AW: String-Ende mit while finden
 
Zitat:

Zitat von Caps (Beitrag 1471697)
Length liefert NICHT die Zeilenumbrüche mit?
Das würde mich jetzt aber aus der Bahn werfen...

Schonmal ausprobiert?
Delphi-Quellcode:
var
  s : String;
begin
  s := '>' + #13#10#13#10#13#10 + '<';
  ShowMessage(Format('%s ist %d Zeichen lang.',[s,Length(s)]));
end;
Was kommt denn dabei jetzt raus?
Code:
---------------------------
Editor
---------------------------
>


< ist 8 Zeichen lang.
---------------------------
OK  
---------------------------

Uwe Raabe 12. Aug 2020 15:13

AW: String-Ende mit while finden
 
Nur nochmal zur Klärung: Strings und AnsiStrings in Delphi enthalten immer ein abschließendes 0-Zeichen. Daher ist eine Umwandlung in PChar bzw. PAnsiChar nicht nötig. Allerdings muss man aufpassen, wenn man den String an diesem Punkt indiziert, da das 0-Byte bzw. 0-Word außerhalb des gültigen Bereichs liegt. Zur Not kann man dann aber die Bereichsprüfung abschalten.

Lange String-Typen

himitsu 12. Aug 2020 15:27

AW: String-Ende mit while finden
 
Ja, es zählt die Zeichen, und sollte ein Zeilenumbruch 2 Zeichen lang sein, dann sind das eben auch 2 Zeichen und nicht 1.
Man darf vorher gern #13#10 durch #10 ersetzen, oder man muß die Zählfunktion anpassen.

Zitat:

Zitat von Uwe Raabe (Beitrag 1471714)
Daher ist eine Umwandlung in PChar bzw. PAnsiChar nicht nötig.

Ja, aber wenn du über S[x] zugreifst und die Indexprüfung aktiv ist, dann raucht es, sobald du auf diese impliziten #0 zugreifen willst.

Caps 13. Aug 2020 09:18

AW: String-Ende mit while finden
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1471709)
Zitat:

Zitat von Caps (Beitrag 1471697)
Length liefert NICHT die Zeilenumbrüche mit?
Das würde mich jetzt aber aus der Bahn werfen...

Schonmal ausprobiert?
Delphi-Quellcode:
var
  s : String;
begin
  s := '>' + #13#10#13#10#13#10 + '<';
  ShowMessage(Format('%s ist %d Zeichen lang.',[s,Length(s)]));
end;
Was kommt denn dabei jetzt raus?
Code:
---------------------------
Editor
---------------------------
>


< ist 8 Zeichen lang.
---------------------------
OK  
---------------------------


Das ist genau das Verhalten, was ich erwarten würde; Length zählt die Umbrüche mit.
Etwas anderes hätte mich gewundert.

lg Caps

himitsu 14. Aug 2020 13:42

AW: String-Ende mit while finden
 
Delphi-Quellcode:
'>'#13#10#13#10#13#10'<' = 8
'>'#10#10#10'<' = 6
'hätte' = 5
'ha'#$0308'tte' = 6
Tja, wenn man die Char's zählt, dann bekommt man eben auch die Anzahl der Chars.

Im Notfall muß man eben vorher den String "normalisieren", wenn man was Anderes haben will.

Denn egal ob ich #13#10 als EINS zähle
oder ob ä und ä (a¨ > Combining Diaeresis) für "mich" das Gleiche sind,
für den Computer ist es das nur dann, wenn ich es ihm sage.



Delphi-Quellcode:
if 'hätte' = 'ha'#$0308'tte' then // das hier schmeißt direkt der Compiler raus
  Sleep(100){False};
S := 'ha'#$0308'tte';
if 'hätte' = S then // ähnlich CompareStringOrdinal
  Sleep(100){False};
if CompareStringOrdinal('hätte', 5, 'ha'#$0308'tte', 6, False) = CSTR_EQUAL then
  Sleep(100){False};
if CompareString(LOCALE_USER_DEFAULT, LINGUISTIC_IGNOREDIACRITIC, 'hätte', 5, 'ha'#$0308'tte', 6) = CSTR_EQUAL then
  Sleep(100){True};
https://www.compart.com/en/unicode/U+0308
https://en.wikipedia.org/wiki/Combining_character


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:54 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz