eine const mit allen Buchstaben: Wie deklarieren?

Für Fragen von Einsteigern und Programmieranfängern...
SiMoeBoe
Beiträge: 28
Registriert: So 13. Mär 2011, 22:16
OS, Lazarus, FPC: Ubuntu (L 0.9.28.2-10ubuntu1 FPC 2.4.0)

eine const mit allen Buchstaben: Wie deklarieren?

Beitrag von SiMoeBoe »

Moin Leute,

Auf der Suche nach einer praktischen Funktion, um ein Zeichen auf seine Art (Buchstabe,Zahl,Sonstiges) zu überprüfen, bin ich auf einer Seite (http://www.delphipraxis.net/74456-string-auf-buchstaben-testen.html) auf folgenden Code gestoßen:

Code: Alles auswählen

type
   TCharSet = Set of Char;
 
const
  LCASE = ['a'..'z', 'ä', 'ö', 'ü'];
  UCASE = ['A'..'Z', 'A', 'Ö', 'Ü'];
  ALPHA = LCASE + UCASE + ['ß'];
 
function ContainsOnly(const s: String; chars: TCharSet): Boolean;
var
  i: Integer;
begin
  i := Length(s);
  Result := s <> ''; // eine Frage der Definition ...
  while Result and (i > 0) do
  begin
    Result := s[i] in chars;
    Dec(i);
  end;
end;


Laut Autor funktionstüchtig, jedoch eben Delphi.
Wenn ichs nun in Lazarus nutze hab ich bei der Definition der Constanten ab

Code: Alles auswählen

LCASE = ['a'..'z', 'ä', 'ö', 'ü'];

folgende Fehlermeldung: Error: Ordinal expression expected

Kann es sein, dass ich es Lazarusbedingt anders schreiben muss? Wenn ja, wie?

Vielen Dank im voraus und Viele Grüße,
SiMoeBoe
Woran du glaubst, dafür sollst du leben und sterben.

MmVisual
Beiträge: 1445
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: eine const mit allen Buchstaben: Wie deklarieren?

Beitrag von MmVisual »

Das liegt an der UTF8 Codierung. Ein ä wird als 2-Byte Code dargestellt und das passt nicht in ein CHAR (Byte).
Ich weiß jetzt aber nicht wie man das ä als ANSI-Konstante in das Array bekommt.

Deine Routine müsste dann mit UTF8ToSys() den String in ein ANSI-String wandeln.
Oder man müsste WChar nehmen (klappt aber nicht ohne weiteres).
Oder als Array[0..22] of String[2] deklarieren.

Probiere es mal aus und poste das Ergebnis.
EleLa - Elektronik Lagerverwaltung - www.elela.de

MmVisual
Beiträge: 1445
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: eine const mit allen Buchstaben: Wie deklarieren?

Beitrag von MmVisual »

Code: Alles auswählen

type
   TCharSet = Set of Char;
 
const
  LCASE = ['a'..'z', #228, #246, #252];
  UCASE = ['A'..'Z', #196, #214, #220];
  ALPHA = LCASE + UCASE + [#223];
 
function ContainsOnly(s: String; chars: TCharSet): Boolean;
var
  i: Integer;
begin
  s := UTF8ToSys(s);
  i := Length(s);
  Result := s <> ''; // eine Frage der Definition ...
  while Result and (i > 0) do
  begin
    Result := s[i] in chars;
    Dec(i);
  end;
end;


Kompilieren geht, Funktion nicht getestet...
EleLa - Elektronik Lagerverwaltung - www.elela.de

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

Re: eine const mit allen Buchstaben: Wie deklarieren?

Beitrag von theo »

So geht das nicht wirklich. Du gehst schon von einer bestimmten Kodierung aus, wenn du z.B mit #228 arbeitest.
Unter Linux wird das nicht klappen, da dort nur mit UTF-8 und nicht mit Ansi gearbeitet wird.

Sauber lösen kannst du das mit meiner TCharacter Klasse in character.pas:
http://wiki.lazarus.freepascal.org/Theodp

SiMoeBoe
Beiträge: 28
Registriert: So 13. Mär 2011, 22:16
OS, Lazarus, FPC: Ubuntu (L 0.9.28.2-10ubuntu1 FPC 2.4.0)

Re: eine const mit allen Buchstaben: Wie deklarieren?

Beitrag von SiMoeBoe »

Moinmoin,
Hab soeben theos Unit eingebaut und zumindest keine Fehlermeldung mehr^^
Leider kann ich noch nicht überprüfen, ob das ganze auch wirklich klappt, aber sobald ich soweit bin, schreib ich es hier.
@theo: Ich habe für die Überprüfung auf Buchstaben 'IsLetter' und für Zahlen 'IsNumber' genutzt.
Ist das so korrekt? Habe nicht ganz durch deine Klassen durchgeblickt, sind mir noch was zu hoch^^
Vielen Dank aber,

MfG,
SiMoeBoe
Woran du glaubst, dafür sollst du leben und sterben.

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

Re: eine const mit allen Buchstaben: Wie deklarieren?

Beitrag von theo »

SiMoeBoe hat geschrieben:@theo: Ich habe für die Überprüfung auf Buchstaben 'IsLetter' und für Zahlen 'IsNumber' genutzt.
Ist das so korrekt?


Im Prinzip schon. Damit prüfst du aber nur einen einzelnen UTF-8 "Buchstaben". Den String durchlaufen musst du also selber wie im Beispiel auf der Wiki Seite.

SiMoeBoe
Beiträge: 28
Registriert: So 13. Mär 2011, 22:16
OS, Lazarus, FPC: Ubuntu (L 0.9.28.2-10ubuntu1 FPC 2.4.0)

Re: eine const mit allen Buchstaben: Wie deklarieren?

Beitrag von SiMoeBoe »

Um so besser^^
Muss sowieso immer nur ein Zeichen auf seine 'Beschaffenheit' überprüfen.
Vielen Dank,
LG; SiMoeBoe
Woran du glaubst, dafür sollst du leben und sterben.

u-boot
Beiträge: 306
Registriert: Do 9. Apr 2009, 10:10
OS, Lazarus, FPC: Ubuntu 9.10 (L 0.9.28 FPC 2.2.4)
CPU-Target: 32Bit
Wohnort: 785..

Re: eine const mit allen Buchstaben: Wie deklarieren?

Beitrag von u-boot »

Ich will hier mal auch noch nen Senf dazugeben.
Meine Lösung wäre für den Zweck ungefähr so (funktioniert zumindest bei mir):

Code: Alles auswählen

const gross='ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ';
      klein='abcdefghijklmnopqrstuvwxyzöüß';
      alle=gross+klein;
function nurbuchstaben(const s:string):boolean;
  var i:integer;
  begin
    result:=true;
    i:=length(s);
    while (i>0) and result do if pos(s[i], alle)=0 then result:=false else dec(i);
  end;


P.S.: Gerne könnt ihr mir beibringen, wo die Nachteile dieser Lösung liegen.
Ubuntu 9.10 (L 0.9.28 FPC 2.4.x)

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

Re: eine const mit allen Buchstaben: Wie deklarieren?

Beitrag von theo »

u-boot hat geschrieben:P.S.: Gerne könnt ihr mir beibringen, wo die Nachteile dieser Lösung liegen.


Das wird imho nicht funktionieren, wenn s einen Umlaut etc. enthält.
Deutsche Umlaute bestehen bei UTF-8 aus zwei Bytes, mit s[i] erreichst du aber zwangsläufig nur das eine Byte (bzw. Char).

Ausserdem ist so eine Lösung nie International tauglich. Was ist nur schon mit éàç? Das sind auch Buchstaben, nur halt keine Deutschen.

MmVisual
Beiträge: 1445
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: eine const mit allen Buchstaben: Wie deklarieren?

Beitrag von MmVisual »

Theo, ich glaube das wird doch funktionieren, denn der String mit Umlaute hat 2 Bytes (oder n Bytes), die, gleichen sind auch Vergleich-String drin. Somit klappt das wieder.
Denke das mal auf Byte-Ebene zu Ende, dann müsstest Du auch auf das gleiche Ergebnis wie ich kommen.
EleLa - Elektronik Lagerverwaltung - www.elela.de

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

Re: eine const mit allen Buchstaben: Wie deklarieren?

Beitrag von theo »

MmVisual hat geschrieben:Denke das mal auf Byte-Ebene zu Ende, dann müsstest Du auch auf das gleiche Ergebnis wie ich kommen.


Verstehe nicht was du meinst.
Ein "ö" besteht z.B. aus der UTF-8 Bytefolge $C3$B6.
Mit einem s[i] gelangst du also zwangsläufig auf das erste Byte $C3. Dieses Zeichen wird in "klein" vorkommen, auch wenn die Konstante "klein" nur ä aber kein ö enthält. Also was willst du damit?

Ausserdem sollte man imho nicht versuchen Unicode auszutricksen, sondern zu verstehen und korrekt anzuwenden.

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: eine const mit allen Buchstaben: Wie deklarieren?

Beitrag von marcov »

SiMoeBoe hat geschrieben:Laut Autor funktionstüchtig, jedoch eben Delphi.


Post ist von 2006, also alter Delphi.

FPC ist (heute) nur teilweise Unicode, und sitzt da zwischen alter und neuer Delphi.

Versuche mal mit $codepage (http://www.freepascal.org/docs-html/prog/progsu81.html) eine ANSI Source Codepage zu setzen, und es solte denzelben SET wie alter Delphi generieren mussen.

(alter Delphi -> Quellen sind Standard in ansi encoding. Neuer Delphi und FPC -> Quellen sind UTF8 )

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

Re: eine const mit allen Buchstaben: Wie deklarieren?

Beitrag von theo »

marcov hat geschrieben:Versuche mal mit $codepage


Denn Tipp halte ich für nicht besonders gut. Lieber auf Unicode umstellen, es ist ja alles da, statt auf Ansi rumreiten.

u-boot
Beiträge: 306
Registriert: Do 9. Apr 2009, 10:10
OS, Lazarus, FPC: Ubuntu 9.10 (L 0.9.28 FPC 2.2.4)
CPU-Target: 32Bit
Wohnort: 785..

Re: eine const mit allen Buchstaben: Wie deklarieren?

Beitrag von u-boot »

theo hat geschrieben:
Das wird imho nicht funktionieren, wenn s einen Umlaut etc. enthält.
Deutsche Umlaute bestehen bei UTF-8 aus zwei Bytes, mit s[i] erreichst du aber zwangsläufig nur das eine Byte (bzw. Char).

Ausserdem ist so eine Lösung nie International tauglich. Was ist nur schon mit éàç? Das sind auch Buchstaben, nur halt keine Deutschen.


Nun mein Vorschlag soll einfach prüfen, ob alle Zeichen eines strings teil eines zulässigen Alphabets sind. Das zulässige Alphabet wird durch die Konstanten angegeben.

-> Wenn die Zeichen éàç teil des zulässigen Alphabets sein sollen müssen diese einfach in den Konstanten aufgenommen werden. Ist imho ohne Probleme machbar.

Sollte was an meinem Vorschlag nicht funktionieren, bitte ein 'zulässiges Alphabet' und einen zu überprüfenden string angeben, wo etwas zu einem falschen Ergebnis führt. Dann könnt ich die Kritik nachvollziehn.

Meine Idee war übrigens nicht 'ich trickse UTF-8 aus', sondern ich vergleiche lieber strings und schlag mich nicht so gern mit char rum.

P.S.: In meinem letzten Beitrag habe ich das 'ä' im zulässigen Alphabet vergessen.
Ubuntu 9.10 (L 0.9.28 FPC 2.4.x)

MmVisual
Beiträge: 1445
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: eine const mit allen Buchstaben: Wie deklarieren?

Beitrag von MmVisual »

>> Meine Idee war übrigens nicht 'ich trickse UTF-8 aus'

Mit dem Code "s[i]" hast du genau das gemacht. Dennoch sollte dein Code fehlerfrei funktionieren.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Antworten