Mengen definieren

Für Fragen von Einsteigern und Programmieranfängern...
Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: Mengen definieren

Beitrag von theo »

mschnell hat geschrieben:Wenn vor dem Abprüfen auch nur eines Zeichens, der String komplett umcodiert wird,
Und wie kommst du jetzt darauf?
Hast du dir den UTF8Scanner mal angeschaut?
Offenbar nicht.

tictac
Beiträge: 23
Registriert: Di 3. Apr 2012, 11:30

Re: Mengen definieren

Beitrag von tictac »

theo hat geschrieben: Erklär doch mal, was du am Ende erreichen willst, so geht das leider nicht.
anscheinend hab ich hier ne heftig diskussion losgetreten...

ich möchte eigentlich nur überprüfen, ob in einem string, den ein anwender eingibt, nur korrekte zeichen (also die würde ich halt gern festlegen) drin sind.
(wenn das mit dem ß nicht geht, wäre das auch nur halb so schlimm)

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

Re: Mengen definieren

Beitrag von theo »

tictac hat geschrieben: anscheinend hab ich hier ne heftig diskussion losgetreten...
Mach dir keine Sorgen, das hat nichts mir dir zu tun.
Unicode ist ein rotes Tuch in diesem Forum. Da müssen alle ihr (halb-)Wissen loswerden. :wink:
tictac hat geschrieben: ich möchte eigentlich nur überprüfen, ob in einem string, den ein anwender eingibt, nur korrekte zeichen (also die würde ich halt gern festlegen) drin sind.
(wenn das mit dem ß nicht geht, wäre das auch nur halb so schlimm)
Ob mit oder ohne öäü oder ß etc. ist natürlich die entscheidende Frage.
Oder anders gesagt, wenn du nur Zeichen aus dem ASCII Bereich brauchst, geht's mit sets, sonst nicht.
Beide Varianten sind eigentlich schon aufgezeigt worden.

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: Mengen definieren

Beitrag von mschnell »

theo hat geschrieben:Hast du dir den UTF8Scanner mal angeschaut?
Offenbar nicht.
Wenn der Scanner "s.UTF8Chars" kann, muss er entweder alles schon vorher gescannt und katalogisiert haben (immenser Zusatz-Aufwand bei UTF8Chars[1] ) oder er muss bei jedem Aufruf von UTF8Chars alles von vorne scannen (immenser Zusatz-Aufwand bei UTF8Chars[10000000] , .. , UTF8Chars[10000001] .

Dagegen würde nur ein Iterator (also "s.NextUTF8Char") helfen (ist ja vermutlich auch schon drin.)

Man kann natürlich auch genial sein und sich hinter den Kulissen einen Cache von Zeichen -> Code Zuordnungen halten, und dann immer vom nächstgelegenen Eintrag ab suchen. Das traue ich Dir durchaus zu ! :D

(Interessante Frage: Was ist die intelligenteste Methode, alte Cache-Eintrage zu löschen: wirklich den ältesten oder vielleicht eher einen der nicht sehr weit entfernt von seinen nächsten Nachbarn liegt. )

Ich schaue mir den Sourcecode morgen 'mal genau an.

-Michael
Zuletzt geändert von mschnell am So 22. Apr 2012, 13:14, insgesamt 1-mal geändert.

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

Re: Mengen definieren

Beitrag von theo »

mschnell hat geschrieben:
theo hat geschrieben:Hast du dir den UTF8Scanner mal angeschaut?
Offenbar nicht.
Wenn der Scanner "s.UTF8Chars" kann muss er entweder alles schon vorher gescannt und katalogisiert haben (immenser Zusatz-Aufwand bei UTF8Chars[1] ) oder er muss bei jedem Aufruf von UTF8Chars alles von vorne scannen (immenser Zusatz-Aufwand bei UTF8Chars[10000000] (immenser Zusatz-Aufwand bei UTF8Chars[10000001]

Dagegen würde nur ein Iterator (also "s.NextUTF8Char") helfen (ist ja vermutlich auch schon drin.)

Ich schaue mir den Sourcecode morgen 'mal genau an.



Oder er merkt sich die letzte Position und macht von dort aus weiter???

Sorry mschnell, den UTF8Scanner gibt es seit Feb. 2009, und du weisst das.
http://www.lazarusforum.de/viewtopic.ph ... 70&p=28094" onclick="window.open(this.href);return false;

Dass du dich noch nie damit befasst hast, zeigt mir einfach, dass du dich nicht für Lösungsansätze interessierst - lieber labern und jammern.

Dass du dann auch noch Unsinn behauptest, über etwas was du dir noch nicht mal angeschaut hast, finde ich ziemlich dreist.

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: Mengen definieren

Beitrag von mschnell »

(Deine Antwort kam schon, bevor ich meinen Beitrag verbessert habe: Du hast also tatsächlich einen Cache implementiert, wenn auch anscheinend nur eine Position.)
theo hat geschrieben:Dass du dich noch nie damit befasst hast, zeigt mir einfach, dass du dich nicht für Lösungsansätze interessierst - lieber labern und jammern.
Das hatten wir doch soeben schon im anderen Thread diskutiert: Ich bin tatsächlich nicht an Lösungen von durch Lazarzs/FPC hervorgerufenen Problemen interessiert, sondern ausschließlich an der Verbesserung von Lazarus/FPC selber. Und da gehören die Theo-Tool leider (noch) nicht dazu. (Meine Entschuldigung an ticktack, aber dem hast Du ja geholfen, er war nur nicht ganz zufrieden).

-Michael

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

Re: Mengen definieren

Beitrag von theo »

mschnell hat geschrieben: Ich bin tatsächlich nicht an Lösungen von durch Lazarzs/FPC hervorgerufenen Problemen interessiert, sondern ausschließlich an der Verbesserung von Lazarus/FPC selber. Und da gehören die Theo-Tool leider (noch) nicht dazu.
Und das hat natürlich für dich überhaupt keinen Zusammenhang?
Für jemanden der pausenlos Text zum Thema Unicode verfasst, bist du erstaunlich wenig an praktischen Ansätzen interessiert.
Mindestens als Beispiel (meinetwegen auch wie man es nicht implementieren soll) böten diese Ansätze doch eine (realisierte) Diskussionsgrundlage.

tictac
Beiträge: 23
Registriert: Di 3. Apr 2012, 11:30

Re: Mengen definieren

Beitrag von tictac »

theo hat geschrieben: Ob mit oder ohne öäü oder ß etc. ist natürlich die entscheidende Frage.
Oder anders gesagt, wenn du nur Zeichen aus dem ASCII Bereich brauchst, geht's mit sets, sonst nicht.
also ä,ö und ü brauch ich eh nicht und bei ß wäre es zwar schön... aber nicht tragisch, wenn's nicht geht.
theo hat geschrieben: Beide Varianten sind eigentlich schon aufgezeigt worden.
ja, ich weiß, vielen dank dafür,
ich hab zwar noch irgendwo nen fehler, aber ich bin schonmal echt weitergekommen...

carli
Beiträge: 657
Registriert: Sa 9. Jan 2010, 17:32
OS, Lazarus, FPC: Linux 2.6.x, SVN-Lazarus, FPC 2.4.0-2
CPU-Target: 64Bit

Re: Mengen definieren

Beitrag von carli »

theo hat geschrieben:
mschnell hat geschrieben: Er hat aber recht
Warum?
Das Problem ist die Index-Funktion bei UTF-8-Strings.

Um das 5-te Zeichen auszulesen, kannst du nicht einfach das 5te Byte nehmen und schauen, ob es noch mehr Bytes hat, sondern du musst mit einer Schleife vom ersten Zeichen an zählen und die Zeichenlänge (1 Byte, 2 Byte, 4 Byte) durchzählen.
Ein Iterator hingegen merkt sich die Byte-Position des i-ten Zeichens und kann das i+1-te Zeichen durch "einen Schritt weiter" in O(1) berechnen und muss nicht den String von vorne scannen.

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

Re: Mengen definieren

Beitrag von theo »

@Carli: schon klar, aber woher nimmst du die Erkenntnis, wie TUTF8Scanner funktioniert?
Genau das tut der doch, sonst wäre er ja witzlos.

Das Beispiel, nachdem ich dich hier http://www.lazarusforum.de/viewtopic.php?p=53938#p53938" onclick="window.open(this.href);return false; gefragt habe, bekomme ich das noch?

Heinrich Wolf
Beiträge: 323
Registriert: Di 12. Apr 2011, 13:21
OS, Lazarus, FPC: WinXP + VMWare Player mit Fedora14, L 1.1, FPC 2.7.1
CPU-Target: 1core 1,8GHz 32Bit
Wohnort: Fürth
Kontaktdaten:

Re: Mengen definieren

Beitrag von Heinrich Wolf »

Hallo,

ich hab versucht, folgendes nachzuvollziehen:
mse hat geschrieben:
theo hat geschrieben: Der OP wollte das ß in die Menge aufnehmen. Wie machst du das?
Sets werden mit 16 Bit zu gross. Als Ersatz bietet sich case an:

Code: Alles auswählen

{$codepage utf8}
[...]
var
 ch1: unicodechar;
[...]
 case ch1 of
  'a'..'z','A','ä','ß': begin
  end;
[...]
Dazu hab ich das Beispiel wie folgt vervollständigt:

Code: Alles auswählen

unit main;
 
{$mode objfpc}{$H+}
{$codepage utf8}
 
interface
 
uses
  Classes,
  SysUtils,
  FileUtil,
  Forms,
  Controls,
  Graphics,
  Dialogs,
  StdCtrls;
 
type
 
  { TMainForm }
 
  TMainForm = class(TForm)
    Codes   : TLabel;
    procedure FormCreate(Sender: TObject);
  private
    procedure Bewerte(c : UnicodeChar);
  end;
 
var
  MainForm : TMainForm;
 
implementation
 
{$R *.lfm}
 
{ TMainForm }
 
procedure TMainForm.FormCreate(Sender: TObject);
  begin
    Codes.Caption := '';
    Bewerte('a');
    Bewerte('b');
    Bewerte('ä');
    Bewerte('A');
    Bewerte('B');
    Bewerte('Ä');
  end;
 
procedure TMainForm.Bewerte(c : UnicodeChar);
  begin
    case c of
      'a'..'z','A','ä','ß':
        Codes.Caption := Codes.Caption + c + ' Code ' + IntToStr(ord(c))
                         + ' im Set' + #$0a;
    else
      Codes.Caption := Codes.Caption + c + ' Code ' + IntToStr(ord(c))
                       + ' nicht im Set' + #$0a;
    end;
  end;
 
end.
Was dabei herausgekommen ist, verwirrt mich. Ohne

Code: Alles auswählen

{$codepage utf8}
compiliert es nicht, weil dann 'ä' und 'ß' keine Ordinale sind. Aber warum muss es dazu UTF8 und nicht z.B. UTF16 sein? Wenn ich richtig informiert bin, sind 'ä' und 'ß' bei UTF8 eben KEINE Ordinale, sondern 2-Byte-Code. Auch das Ergebnis auf dem Bildschirm verwirrt mich. Bei 'ä' wird ? Code 228 ausgegeben und bei 'Ä' wird ? Code 196 ausgegeben. Das ist kein Unicode, weder UTF8, noch UTF16, glaub ich, sondern die bei mir eingestellte Windows ANSI Codierung CP1252. Ich finde den Schalter

Code: Alles auswählen

{$codepage utf8}
besonders dadurch unbrauchbar, dass diese Umlaute nicht lesbar, sondern als ? ausgegeben werden.

Gruß
Heiner

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

Re: Mengen definieren

Beitrag von theo »

Aber was ich nie kapiere, und das gilt für carli und mschnell:
Wenn man zu faul ist, sich mit einem Sachverhalt vertraut zu machen, warum reißt man denn dann die Klappe so weit auf?
Warum gibt man dann in frechem Ton Schwachsinn von sich? Das verstehe ich nicht.
Wenn ich keinen Dunst habe, dann schweige ich und hoffe, dass es keinem auffällt.
Ist das ein Generationen-Ding oder etwas ethnisches?

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

Re: Mengen definieren

Beitrag von theo »

@Heinrich Wolf: Das wird dir mse erklären, ich halte mich da lieber raus. :wink:

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: Mengen definieren

Beitrag von mse »

Heinrich Wolf hat geschrieben: Was dabei herausgekommen ist, verwirrt mich.
Du bist hier auf einen Nachteil der von Lazarus gewählten Art der Unicode Unterstützung mit FPC gestossen. Bei Lazarus Programmen die auf visuelle Komponenten zugreifen, darf {$codepage utf8} oder der Compiler-Parameter -Fcutf8 nicht angegeben werden. Der Hintergrund:
{$codepage utf8} sagt FPC, dass der Quelltext in utf-8 vorliegt. Die Konstante 'ä', welche im utf8 Quelltext als #$c3#$a4 vorliegt, wird dann vom Compiler nicht als 8 Bit string mit 2 Zeichen interpretiert, sondern als 16 Bit Zeichen U+00E4.
Es ist übrigens auch möglich in {$codepage xxx} andere Codierungen anzugeben. Bei der Zuweisung

Code: Alles auswählen

{$codepage utf8}
 
var
 uch1: UnicodeChar; //16bit
[...]
 uch1:= 'ä';
steht also der gewünschte Wert #$e4 in uch1. Lazarus arbeitet nun leider nicht mit dem 16Bit string Typen "UnicodeString", sondern mit "string."
Der Typ "string" wird von FPC als 8Bit string in der aktuellen Systemcodierung behandelt. Das ist auf Linux meistens utf-8, auf Windows ist es meistens nicht utf-8. Bei der Zuweisung von Zeichenkonstanten, string-Konstanten und UnicodeString-Variablen auf string wandelt FPC zur Laufzeit automatisch von utf-16 auf die aktuelle 8-Bit Systemcodierung, auf Linux meistens utf-8, auf Windows meistens nicht utf-8. In deinem Fall wandelt FPC auf CP1252. Das ist nun nicht das was Lazarus erwartet, Lazarus erwartet nämlich auf allen Systemen utf-8. Darum die '?'. Fazit: 16bit UnicodeChar und UnicodeString lassen sich in visuellen Lazarus-Programmen ohne explizite Wandlung der Zeichenkonstanten durch UTF8decode() in 16Bit nicht verwenden.
Der Hinweis sei erlaubt, dass es mindestens ein anderes FPC-GUI Entwicklungssystem gibt, welches diesen Nachteil nicht aufweist.
Mit dem neuen cpstrnew in FPC trunk wird es noch etwas deftiger, da stellt Lazarus so viel ich weiss die FPC-Systemcodierung in Windows auf utf-8, was in den meisten Fällen nicht zutreffen wird. Vielleicht kann das ein Lazarus Spezialist bestätigen oder dementieren.

Martin
Zuletzt geändert von mse am So 22. Apr 2012, 19:34, insgesamt 1-mal geändert.

carli
Beiträge: 657
Registriert: Sa 9. Jan 2010, 17:32
OS, Lazarus, FPC: Linux 2.6.x, SVN-Lazarus, FPC 2.4.0-2
CPU-Target: 64Bit

Re: Mengen definieren

Beitrag von carli »

theo hat geschrieben:Aber was ich nie kapiere, und das gilt für carli und mschnell:
Wenn man zu faul ist, sich mit einem Sachverhalt vertraut zu machen, warum reißt man denn dann die Klappe so weit auf?
Warum gibt man dann in frechem Ton Schwachsinn von sich? Das verstehe ich nicht.
Wenn ich keinen Dunst habe, dann schweige ich und hoffe, dass es keinem auffällt.
Ist das ein Generationen-Ding oder etwas ethnisches?
Wer hat dir denn auf den Schlips getreten?

Nunja, nach ein bisschen ausprobieren, musste ich feststellen, dass FPC 2.4.4-3.1 utf8string mit for..in auch nur wie einen String behandelt und nicht wirklich die UnicodeChars da raussaugt.
Schau dir aber mal das Topic an, die Fragenstellung und erkenne, dass du hier ziemlich vom Thema abdriftest.
Dass man UTF8Strings mit Iteratoren um Größenordnungen schneller traversieren kann als mit einem for über den Index, sollte dir ja klar sein.

Du willst ein funktionierendes FPC-Beispiel? Lies selbst: http://wiki.freepascal.org/for-in_loop" onclick="window.open(this.href);return false;
(Ist auf FPC 2.4 gemünzt. Du brauchst mit deinem 2.6 gar nicht so angeben)

Antworten