Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Pos() oder AnsiPos()? (https://www.delphipraxis.net/125919-pos-oder-ansipos.html)

blackdrake 14. Dez 2008 22:16


Pos() oder AnsiPos()?
 
Hallo.

Ich bin mal wieder am Überarbeiten meiner Codes.

Mir ist Letztens folgendes aufgefallen: Ich habe stets UpperCase(), LowerCase() oder z.B. Pos() verwendet. Es gibt aber zu all diesen Funktionen auch die Ansi-Varianten, wie z.B. AnsiPos().

Nun, der Vorteil an AnsiUpperCase() ist z.B. dass es MBCS (= Unicode?) unterstützt. Außerdem werden auch deutsche Umlaute wie z.B. das ä behandelt.

Nun stellt sich die Frage: Wenn die Ansi-Varianten also "besser" sind, wieso sollte man die Nicht-Ansi-Varianten überhaupt noch verwenden? (Sehen wir mal von Inkompatibilitäten bezüglich groß- oder nicht-groß- geschriebenen äöü ab)

Außerdem:
1. Wieso meldet Delphi z.B. das Symbol Pos() nicht als veraltet?
2. Wieso hat Delphi trotzdem noch Code für z.B. Pos() implementiert und leitet nicht auf AnsiPos() um?

Delphi-Quellcode:
function Pos(const Substr, S: string): Integer;
begin
  result := AnsiPos(Substr, S);
end;
Ist es legitim, alle Codes, die ich z.B. aus der CodeLib übernommen habe, innerhalb meines Projektes einfach Pos() -> AnsiPos() umzuwandeln, um bei einem eventuellen Delphi 2009 Umstieg möglichst Unicode-Ready zu sein?

Gruß
blackdrake

jbg 14. Dez 2008 23:26

Re: Pos() oder AnsiPos()?
 
UpperCase und LowerCase nutzt man dann wenn man Geschwindigkeit braucht und nur den ASCII Zeichensatz verwendet.

AnsiPos und Pos arbeiten in Delphi 2009 gleich, nur das Pos schneller ist weil ein besserer Algorithmus verwendet wird.

Ich habe AnsiPos noch nie verwendet, da ich nur für westliche Sprachen programmiere und diese keine MBCS nutzen und somit alle Char eindeutig sind. Mit Unicode ist das aber hinfällig, weil dort jeder Char auch für östliche Sprachen eindeutig ist.

himitsu 15. Dez 2008 00:45

Re: Pos() oder AnsiPos()?
 
Bei Pos ist es so, das dort automatisch die passende Version für AnsiString oder WideString gewählt wird.

Wenn du deinen "String" als String definierst, wird dort Seit Delphi 2009 standardmäßig Unicode (WideString) verwendet ... in den früheren Delphi-Versionen ist es AnsiString.
Ebenso ist es mit Char. (D09 = WideChar und davor AnsiChar)

In der WinAPI ist es ebenso geregelt ... dort gibt es Ansi- (abcA), Unicode- (abcW) und die Standard-Versionen (abc), wobei Letztere wiederrum entsprechend der umgebung auf die Ansi- oder UnicodeVersionen umgeleitet werden.


Also, mit den von dir "alt" genannten Versionen kann man ein Programm erstellen und dann erst später, beim Compilieren, entscheiden, ob es ein Ansi- oder Unicode-Programm werden soll.

blackdrake 15. Dez 2008 00:48

Re: Pos() oder AnsiPos()?
 
Heißt das, Pos() wird bei Delphi2009 einen WideString, also Unicode-String korrekt behandeln, AnsiPos() aber nicht? Dann wäre ja Pos() wieder die bessere Wahl, oder?

Und wie ist es bei AnsiUpperCase()? Mir scheint es, als ob das die "bessere" Variante wäre, weil äöü uppercas'ed wird im Gegensatz zu UpperCase().

himitsu 15. Dez 2008 00:56

Re: Pos() oder AnsiPos()?
 
hatte oben noch was zueditiert (wärend du schriebst)


Nja, eigentlich wäre es schönder, wenn Delphi standardmäßig (vor D09) an die "richtigen" Ansi-Versionen umleiten würde.

Also Pos an AnsiPos ... leider macht es dieses nicht immer so :?


Wenn du aus jeden Fall nur mit ANSI arbeiten willst, dann währe theoretisch AnsiPos und Co. wohl die bessere Wahl ... aber wenn du dann doch mal auf Unicode umstellen willst, dann mußt du dann alles auf Unicode umschreiben.


Selber arbeite ich oft direct mit den Unicode-Versionen (außer Pos, denn dieses wird bei einem UnicodeString richtig an die UnicodeVersion weitergeleitet) ... arbeite schon seit Delphi 7 oftmals mit Unicode (siehe FileSplitter und Co.).

Wenn es dir nicht auf den Speicher ankommt, wäre es dann wohl doch besser statt die Ansi-Versionen direkt zu verwenden die UnicodeVersionen zu verwenden (dort hat man dann volle Unterstützung für Unicode und keine Probleme mit CodePages und Co.)

mkinzler 15. Dez 2008 05:33

Re: Pos() oder AnsiPos()?
 
Aber String (ab D2009) = UnicodeString <> WideString

jbg 15. Dez 2008 11:29

Re: Pos() oder AnsiPos()?
 
  • Pos(string)
    Delphi 2009: Korrektes Unicode
    Delphi 2007: auf Byte-Basis
  • Pos(AnsiString)
    Delphi 2009: auf Byte-Basis (Vorsicht, Delphi bevorzugt Pos(string) bei Stringliteralen)
    Delphi 2007: auf Byte-Basis
  • AnsiPos(string)
    Delphi 2009: Korrektes Unicode (langsamerer Algorithmus als Pos(string))
    Delphi 2007: Korrektes ANSI
  • AnsiPos(AnsiString)
    Delphi 2009: Korrektes ANSI
    Delphi 2007: Korrektes ANSI
  • UpperCase(string)
    Delphi 2009: ASCII (Zeichen #0..#128 werden konvertiert, Umlaute gehören nicht dazu)
    Delphi 2007: ASCII (Zeichen #0..#128 werden konvertiert, Umlaute gehören nicht dazu))
  • UpperCase(AnsiString)
    Delphi 2009: ASCII (Zeichen #0..#128 werden konvertiert, Umlaute gehören nicht dazu)
    Delphi 2007: ASCII (Zeichen #0..#128 werden konvertiert, Umlaute gehören nicht dazu))
  • AnsiUpperCase(string)
    Delphi 2009: Korrektes Unicode
    Delphi 2007: Korrektes ANSI
  • AnsiUpperCase(AnsiString)
    Delphi 2009: Korrektes ANSI
    Delphi 2007: Korrektes ANSI
  • LowerCase/AnsiLowerCase wie UpperCase/AnsiUpperCase

himitsu 15. Dez 2008 12:06

Re: Pos() oder AnsiPos()?
 
Zitat:

Zitat von jbg
  • AnsiPos(string)
    Delphi 2009: Korrektes Unicode (langsamerer Algorithmus als Pos(string))
    Delphi 2007: Korrektes ANSI

eigentlich hätt ich vermutet das für D09 müßte falsch sein, da Ansi Ansi entgegennimmt,
aber statt AnsiString in der Definition find ich was Anderes :shock:
Delphi-Quellcode:
function AnsiPos(const Substr, S: string): Integer;

blackdrake 15. Dez 2008 16:02

Re: Pos() oder AnsiPos()?
 
Hallo.

jbg, danke für diese sehr ausführliche und Übersichtliche Auflistung.

Ok, dann bleibe ich bei den Ansi* Varianten mit den Delphi-Strings (also dem Typ "String").

Damit bin ich bei Delphi 2009 Unicode-Ready und bei Delphi 2007- kompatibel bezüglich Umlauten.

Schade, dass Delphi 2009 bei AnsiPos() und Pos() das selbe Verhalten hat, aber AnsiPos() langsamer ist. Aber das ist irgendwie nicht mein Problem, da Delphi 2009 ja die Funktion einfach als Alias umleiten könnte. Deswegen plage ich mich nicht extra mit Compilerschaltern rum. Es kommt bei meinen Pos-Aufrufen auch nicht auf jede Millisekunden an, da ich nicht mit großen Datenmengen arbeite.

PS: Gibt es eine Erklärung, wieso Delphi 2009 bei Pos() und AnsiPos() scheinbar GLEICHE Funktionen, aber unterschiedlich schnelle Algorithmen verwendet? Ist das Verhalten vielleicht doch nicht identisch? Oder haben die den Alias der Funktion AnsiPos -> Pos wirklich vergessen?

Gruß
blackdrake

jbg 15. Dez 2008 17:28

Re: Pos() oder AnsiPos()?
 
Zitat:

Zitat von blackdrake
Damit bin ich bei Delphi 2009 Unicode-Ready und bei Delphi 2007- kompatibel bezüglich Umlauten.

Wenn du (wie ich weiter oben bereits geschrieben habe) dein Programm nur in westlichen Sprachen (Englisch, Deutsch, Französisch, Italienisch, Spanisch, ...) vertreibst, dann kannst du auch Pos() für Umlaute hernehmen, da die CodePage keine Multi-Byte Sequenzen hat.

Zitat:

PS: Gibt es eine Erklärung, wieso Delphi 2009 bei Pos() und AnsiPos() scheinbar GLEICHE Funktionen, aber unterschiedlich schnelle Algorithmen verwendet?
Klar gibt es eine Erklärung: AnsiPos(string) wurde von AnsiPos(AnsiString) kopiert und dann auf Unicode umgeschrieben. Pos(string) wurde von Pos(AnsiString) kopiert und der Assemblercode dann an Unicode angepasst. UTF16 hat nun mal den Vorteil, dass man sich durch die Char-Sequenz angeln kann ohne dass man Probleme bekommt, wenn man auf ein High oder Low Surogate Zeichen stößt. Bei ANSI ist das (leider) nicht der Fall. Wenn man da mitten im String anfängt, kann es sein, dass man ein LeadByte übersieht und der ganze String falsch interpretiert wird.

Zitat:

Ist das Verhalten vielleicht doch nicht identisch?
Es ist identisch dank UTF16.

Zitat:

Oder haben die den Alias der Funktion AnsiPos -> Pos wirklich vergessen?
Das glaube ich auch. AnsiPos(string) versucht immer gleich den gesamten String für jedes Zeichen zu vergleichen, wohingegen Pos() erstmal das erste Zeichen sucht und dann einen Gesamt-Vergleich durchführt.

nicodex 15. Dez 2008 18:05

Re: Pos() oder AnsiPos()?
 
Zitat:

Zitat von jbg
UTF16 hat nun mal den Vorteil, dass man sich durch die Char-Sequenz angeln kann ohne dass man Probleme bekommt, wenn man auf ein High oder Low Surogate Zeichen stößt.

UTF-16 hat auch Low/High-Surrogates, um Zeichen jenseits der BMP zu codieren (wird von Windows XP und Office unterstützt).

edit: Ich wollte nur darauf hinweisen, dass die Funktionen UCS-2 anstatt UTF-16 implementieren. Egal.

jbg 15. Dez 2008 18:25

Re: Pos() oder AnsiPos()?
 
Zitat:

Zitat von nicodex
UTF-16[/url] hat auch Low/High-Surrogates, um Zeichen jenseits der BMP zu codieren (wird von Windows XP und Office unterstützt).

Hab ich denn was anderes behauptet? Bei UTF16 kann man aber beim Durchparsen des Strings die Surrogates ignorieren, da sie es keine Überschneidung mit der BMP gibt. Bei ANSI gibt es jedoch Überschneidungen bei den Tail-Bytes. Auf mehr wollte ich (und bin ich nicht) hinaus.

messie 2. Jul 2009 09:53

Re: Pos() oder AnsiPos()?
 
Zitat:

Zitat von mkinzler
Aber String (ab D2009) = UnicodeString <> WideString

Ich muss das hier mal wieder aufwärmen, weil ich bei der Umstellung auf 2009 drüber stolpere:
der Compiler wirft mir vor: doppeldeutiger überladener Aufruf von 'Pos'. Die Codezeile:
Delphi-Quellcode:
Pos(WideText,ComboBox1.Items.Strings[i])
Ich fühle mich nicht schuldig.
WideText ist deklariert als WideText = WideString('Hello World'), was mir in der IDE als string angegeben wird, Die ComboBox ist eine TTntComboBox, die auch echte Widestrings liefert(IDE: "Returns System.string").
Offensichtlich macht 2009 einen falschen Redirect (ein cast ist das ja nicht wirklich) auf string, denn
Delphi-Quellcode:
Pos(WideText,WideString(ComboBox1.Items.Strings[i]))
funktioniert

Wie ist denn der Umgang für D2009 korrekt? Kommt man da ohne Änderungen dran? Denn ich habe das in meinen Quellen oft verwendet.


Grüße, Messie

himitsu 2. Jul 2009 10:33

Re: Pos() oder AnsiPos()?
 
als was ist denn WideText definiert?
ist das eine Konstante?

dann laß mal in D2009 das WideString() dort weg :gruebel:

messie 2. Jul 2009 11:13

Re: Pos() oder AnsiPos()?
 
Zitat:

Zitat von himitsu
dann laß mal in D2009 das WideString() dort weg :gruebel:

Nee, das ist schon da und zwar seit Jahren.

Delphi-Quellcode:
const
  WideText = WideString('Hallo');
Als als typunabhängige Konstante. Und dabei scheint was schief zu gehen, denn
Delphi-Quellcode:
const
  WideText : WideString = WideString('Hallo');
scheint zu klappen.

Grüße, Messie


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:07 Uhr.

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