[gelöst] Strings zeichenweise durchgehen

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Joz
Beiträge: 40
Registriert: Mo 27. Mai 2013, 13:16
OS, Lazarus, FPC: Arch Linux, OpenSuse 13.2, Lazarus 1.4
CPU-Target: AMD64
Wohnort: Berlin

[gelöst] Strings zeichenweise durchgehen

Beitrag von Joz »

Hallo,
Ich versuche in einem Projekt, Zeichenketten nach gebräuchlichen Buchstaben zu durchsuchen. Hierzu verwende ich eine While-Schleife und ein Case-Statement, mit dem ich jedes Zeichen prüfe.
Leider scheitere ich schon an diesem einfachen Vorhaben, weil bestimmte Sonderzeichen mehrere Zeichen einnehmen. Wie zum Beispiel 'ä'.
Folgender Code findet bei mir kein kleines Ä.

Code: Alles auswählen

  for i := 1 to Length(S) do
    if S[i] = 'ä' then
      Writeln('ä bei ', i, ' gefunden!')
Grund ist: 'ä' ist kein Char, sondern ein String mit zwei Zeichen Länge. Um eins zu finden, müsste ich nach diesem Substring suchen.
Hierzu meine Frage:
Gibt eine Möglichkeit, jedes sichtbare Zeichen in einem String durchzugehen? Oder einen Compilerschalter, damit strings als char array angesprochen werden können?
Zuletzt geändert von Joz am So 2. Feb 2014, 15:24, insgesamt 1-mal geändert.

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2822
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Strings zeichenweise durchgehen

Beitrag von m.fuchs »

Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Strings zeichenweise durchgehen

Beitrag von mschnell »

If S = 'ä'
Der Compiler macht da wohl gemeiner weise keine Fehlermeldung, obwohl er etwas tut, was keiner beabsichtigt:
der Character S wird in einen String verwandelt und mit dem String 'ä' (der zwei UTF-8Zeichen lang ist) per String-compare verglichen.

"ä" ist bei UTF 8 kein "Zeichen", bei UTF16 wäre es eines. Lazarus kann sowohl mit UTF8 als auch mit UTF16 Strings (Widestrings) arbeiten.

Wenn Du UTF8 verwenden willst: Für solche Zwecke sind Iteratoren das ideale Werkzeug.

Wenn ich mich recht erinnere hatte Theo hier mal einen UTF8-Iterator veröffentlicht.

(Eigentlich sollte Lazarus sowas out of the box zur Verfügung stellen... )

-Michael

Benutzeravatar
theo
Beiträge: 10900
Registriert: Mo 11. Sep 2006, 19:01

Re: Strings zeichenweise durchgehen

Beitrag von theo »

mschnell hat geschrieben: Wenn ich mich recht erinnere hatte Theo hier mal einen UTF8-Iterator veröffentlicht.
Gibt's hier:
http://www.lazarusforum.de/viewtopic.ph ... 94&p=54025

Benutzeravatar
Ally
Beiträge: 283
Registriert: Do 11. Jun 2009, 09:25
OS, Lazarus, FPC: Win und Lazarus Stable release
CPU-Target: x64

Re: Strings zeichenweise durchgehen

Beitrag von Ally »

Hallo,

so könnte es gehen:

Code: Alles auswählen

  for i := 1 to UTF8Length(S) do
    if UTF8Copy(S, i, 1) = 'ä' then
      Writeln('ä bei ', i, ' gefunden!')
http://lazarus-ccr.sourceforge.net/docs ... ength.html
http://lazarus-ccr.sourceforge.net/docs ... 8copy.html

Gruß

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Strings zeichenweise durchgehen

Beitrag von mschnell »

Nur dass "i" dabei keinerlei Aussagekraft hat.

-Michael

Benutzeravatar
theo
Beiträge: 10900
Registriert: Mo 11. Sep 2006, 19:01

Re: Strings zeichenweise durchgehen

Beitrag von theo »

mschnell hat geschrieben:Nur dass "i" dabei keinerlei Aussagekraft hat.
Doch, es müsste schon der visuelle Zeichenindex sein.
Der Nachteil zu TUniString ist, dass so jedesmal der String von vorne durchgerattert wird, um die Position zu finden.
TUnistring merkt sich den "Buchstabenzeiger" und muss so nur bei jeder Abfrage eine Position weiter hüpfen.
Das kann sich bei langen Strings schon auf die Performance auswirken.

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Strings zeichenweise durchgehen

Beitrag von mschnell »

Deshalb hatte ich den "Iterator" empfohlen.

-Michael

Joz
Beiträge: 40
Registriert: Mo 27. Mai 2013, 13:16
OS, Lazarus, FPC: Arch Linux, OpenSuse 13.2, Lazarus 1.4
CPU-Target: AMD64
Wohnort: Berlin

Re: Strings zeichenweise durchgehen

Beitrag von Joz »

Vielen Dank für die Antworten! Das scheint ja doch nicht ganz trivial zu sein.
Vor allem Theos Unit finde ich ja sehr ansprechend. Dass dafür aber 400 Zeilen Code überhaupt notwendig waren und es keine in FPC eingebaute Methode gibt, ist denkwürdig.
@msschnell: Mit Widestrings hab ich es auch schon versucht, aber wenn ich versuche, sie zu Readln, bekomme ich auch zwei Zeichen pro 'ö' – kann ich mir aber nicht erklären. :?:
@Ally: Auch die Methode werd ich mir mal merken, für den Fall, dass ich mal nicht immer theos Unit mitschleppen will. Die aber ansonsten mein Problem gelöst hat. Danke!

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Strings zeichenweise durchgehen

Beitrag von mse »

Joz hat geschrieben:Dass dafür aber 400 Zeilen Code überhaupt notwendig waren und es keine in FPC eingebaute Methode gibt, ist denkwürdig.
Die gibt es schon, Lazarus macht lediglich keinen Gebrauch davon.

Joz
Beiträge: 40
Registriert: Mo 27. Mai 2013, 13:16
OS, Lazarus, FPC: Arch Linux, OpenSuse 13.2, Lazarus 1.4
CPU-Target: AMD64
Wohnort: Berlin

FPC statt LCL

Beitrag von Joz »

Aha, und was wäre da so das Vergehen unter reinem FreePascal?
Die Funktionen, die Ally und Theo benutzt haben, waren ja aus LCLProc und LCLType.
Oder wie lese ich UTF16-strings mit Readln so ein, dass Sonderzeichen nur einen Character belegen?

Benutzeravatar
theo
Beiträge: 10900
Registriert: Mo 11. Sep 2006, 19:01

Re: [gelöst] Strings zeichenweise durchgehen

Beitrag von theo »

@Joz: Man muss wissen, dass User mse hier immer wieder Bemerkungen hinterlässt, die darauf abzielen sein eigenes Produkt anzupreisen.
http://www.msegui.org/
Ich habe nichts gegen Martin und sein msegui, aber viele seiner Bemerkungen sind nur mit diesem Hintergrund zu verstehen.

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: FPC statt LCL

Beitrag von mse »

Joz hat geschrieben:Aha, und was wäre da so das Vergehen unter reinem FreePascal?
Unter reinem Free Pascal würde man die unit mit -Fcutf8 oder ${codepage utf8} kompilieren und UnicodeString und UnicodeChar verwenden.
theo hat geschrieben: http://www.msegui.org/
besser
http://sourceforge.net/projects/mseide-msegui/
und
https://gitorious.org/mseide-msegui
Zuletzt geändert von mse am Mo 3. Feb 2014, 15:36, insgesamt 1-mal geändert.

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: [gelöst] Strings zeichenweise durchgehen

Beitrag von mschnell »

theo hat geschrieben:@Joz: Man muss wissen, dass User mse hier immer wieder Bemerkungen hinterlässt, die darauf abzielen sein eigenes Produkt anzupreisen.
"Produkt" ist für etwas, das jeder kostenlos benutzen darf, eine etwas pessimistische Beschreibung.

Ich hatte mse so verstanden, dass es das was Joz sucht, in fpc gibt (und nicht in msegui). Kann aber ein Irrtum sein. Ich kenne jedenfalls nur Deinen Iterator und - falls es sowas in der RTL noch nicht gibt - fände es ziemlich genial, wenn er dort eingebaut würde.

-Michael

Joz
Beiträge: 40
Registriert: Mo 27. Mai 2013, 13:16
OS, Lazarus, FPC: Arch Linux, OpenSuse 13.2, Lazarus 1.4
CPU-Target: AMD64
Wohnort: Berlin

Re: [gelöst] Strings zeichenweise durchgehen

Beitrag von Joz »

Söchen, bin jetzt glücklich geworden mit der Funktion UTF8Decode, die mir einen normalen UTF8 in einen Unicodestring umwandelt, bei dem sowohl for…in als auch die direkte Indizierung von sichtbaren Zeichen ausgehen und Ös und Äs also kein Problem mehr sind. Danke für die Hilfe!

Antworten