[gelöst] Fehler bei Stringkonvertierung

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

[gelöst] Fehler bei Stringkonvertierung

Beitrag von Michl »

Hallo Allerseits,

Hintergrund meines Ausgangsprojekts ist, dass Worte wie " Floß" zu "Floß" oder "Flöhe springen 13 " zu "Flöhe springen" gekürzt werden. Sprich, ich will alle Leerzeichen, Zahlen, Steuerzeichen etc. vor und nach Wörtern entfernen und nur die Wörter erhalten. Ich hatte auch schon Theos UTF8Tools angeschaut und dort die Function "IsLetter" angeschaut, was prinzipiel genau das machen tät, was ich brauch. Allerdings gibt es Probleme, wenn ich die Strings von hinten bereinigen will und ein Sonderzeichen als letztes steht z.B. "ß" bei "Floß" -> das "ß" ist zwei Byte lang, daher ist Str[4] und Str[5] das "ß", sodaß die Byte-weise Durchsicht des Strings von hinten nach vorn nicht geht. Daher dachte ich, ich wandel den Text einfach nach Ansi um, teste dort Byte-weise, lösche ungültige Zeichen und wandel wieder zurück nach UTF8. Gesagt, getan, alles prima, bis ich den String in der Datenbank abfragen will:

Ich habe das Ganze auf folgendes Minimalbsp. reduziert (neue Form, Zconnection und ZQuery drauf):

Code: Alles auswählen

procedure SchreibeByte(Str:String);
var
  i: Integer;
  S: String;
begin
  S:='';
  for i:=0 to High(Str) do
    S:=S + '[' + IntToHex(Byte(Str[i]), 2) + '] ';
  Writeln(S);
end;
 
procedure TForm1.TestSelect;
begin
  ZConnection1.Connected:=True;
  ZQuery1.SQL.Text:='SELECT beschreibung FROM warentabelle WHERE warenname='''+Str+''';';
  ZQuery1.Open;
  Caption:='Suchwort['+Str+'] - Ergebnis['+ZQuery1.Fields[0].AsString+']';
  ZQuery1.Close;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
var
  S: AnsiString;
begin
  Str:='Möhre';
 
  Writeln('String vor Konvertierung:');
  SchreibeByte(Str);
  TestSelect;
 
  S:=UTF8ToAnsi(Str);
  Str:=UTf8Encode(S);
 
  Writeln('String nach Konvertierung:');
  SchreibeByte(Str);
 
  readln;
 
  TestSelect;           //Hier gibt die Exception, siehe angehangenes Bild
end; 
Procedure "Schreibbyte" gibt den String hexadezimal aus
Procedure "TestSelect" versucht etwas aus der Datenbank auszulesen

Beim "FormCreate" startet das Programm:
- es wird "Möhre" als String gesetzt
- die Zeichen des Strings werden im Konsolenfenster ausgegeben
- die Datenbank wird getestet -> funktioniert!!! (auch mit "Möhre")
- der String wird einmal zu Ansi und wieder zurück zu UTF8 konvertiert
- die Zeichen des Strings werden im Konsolenfenster ausgegeben (Die Zeichen sind identisch mit der ersten Ausgabe in der Konsole!!!, siehe unten angehangenes Bild)
- die Datenbank wird erneut getestet, dabei kommt es zum Fehler (siehe angehangenes Bild), die Zeichenkodierung entspricht nicht dem der in der Konsole ausgegebenen Kodierung!

Meine Vermutung ist, dass irgend etwas bei der Konvertierung von Ansi zu UTF8 im Header des Strings stehen geblieben sein muss, dass der String nicht ordentlich als UTF8 gelesen wird?!

Kann jemand den Fehler bestätigen (der konvertierte String fehlerfrei bei "Caption:=Str" angezeigt, Ärger gibts nur bei der Datenbankabfrage)?!
Hat jemand eine Idee zur Problembeseitigung?

Ich nutze Lazarus 1.3 r43268 FPC 2.7.1 (Trunc 25806) i386-win32-win32/win64, ZEOS 7.1.2

Danke
Dateianhänge
Fehler.jpg
Konsole.jpg
Zuletzt geändert von Michl am Di 29. Okt 2013, 12:47, insgesamt 1-mal geändert.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

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

Re: Fehler mit Stringkonvertierung

Beitrag von theo »

Hab nicht alles gelesen, aber ANSI hat bei Unicode nichts verloren.

Wandle nach WideString (UTF8Decode) und verfahre wie gewohnt oder benutze UTF8Scanner.

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: Fehler mit Stringkonvertierung

Beitrag von mse »

theo hat geschrieben: Wandle nach WideString (UTF8Decode)
Vermutlich besser UnicodeString. WideString auf Windows ist nicht Referenz-gezählter OLE-String.

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

Re: Fehler mit Stringkonvertierung

Beitrag von theo »

Ich weiss das im Prinzip, nur ist mir der Unicodestring immer noch nicht ganz geheuer.
Klappt der jetzt und ist der wie bei Dephi?

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: Fehler mit Stringkonvertierung

Beitrag von mse »

UnicodeString gibt es seit vielen Jahren, tatsächlich hatte FPC UnicodeString ( = utf-16 codierter auf allen Platformen Referenz-gezählter string ) vor Delphi. Der anfängliche FPC WideString war was UnicodeString heute ist. Der FPC Windows WideString wurde erst später auf OLE String umgebaut - entgegen meiner lautstarken Opposition wie ich hinzufügen muss. Als Delphi UnicodeString einführte zog FPC nach. Meinst du vielleicht den "code page aware ansi string" aus FPC 2.7.1? Den hat Delphi im neuen LLVM Compiler bereits wieder abgeschafft...

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

Re: Fehler mit Stringkonvertierung

Beitrag von theo »

mse hat geschrieben: Meinst du vielleicht den "code page aware ansi string" aus FPC 2.7.1? Den hat Delphi im neuen LLVM Compiler bereits wieder abgeschafft...
Kann sein. Wie du selber sagst, ist da noch keine Ruhe eingekehrt. Habe irgendwie keine Lust mehr bei sowas die Implementierung "du jour" zu verinnerlichen.
Deshalb halte ich mich an das was ich kenne und wo ich keine Veränderung erwarte.

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: Fehler mit Stringkonvertierung

Beitrag von mschnell »

mse hat geschrieben: Den hat Delphi im neuen LLVM Compiler bereits wieder abgeschafft...
Delphi bietet den LLVM Compiler aber - soweit ich weiß - nur für ARM an. Ist irgendetwas bekannt, dass in Zukunft auch für PC angeboten werden soll ?

Dass Delphi für verschiedene Plattformen unterschiedlich inkompatible Compiler anbietet ist schlicht eine Frechheit. Da ist FPC/Lazarus viel besser.

Ich finde die Idee der "code aware" Strings ja eigentlich nicht schlecht, weil es damit theoretisch möglich ist, in einem Programm mit verschiedenen Codierungen (Unicode und andere) gleichzeitig zu operieren und (theoretisch) eine Umwandlung automatisch genau dann passiert, wenn es nötig ist. Leider ist die Implementierung dafür in FPC (und wenn ich das richtig sehe auch in Delphi) ziemlich unzureichend. (Ansonsten müsste z.B. TStrings und alle Nachfolger einen voll dynamischen String-Type verwenden, damit man ohne Umwandlung jede beliebige Codierung in einer Liste zwischenspeichern kann.)
-Michael
Zuletzt geändert von mschnell am Sa 26. Okt 2013, 21:16, 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: Fehler mit Stringkonvertierung

Beitrag von mschnell »

theo hat geschrieben: Habe irgendwie keine Lust mehr bei sowas die Implementierung "du jour" zu verinnerlichen. Deshalb halte ich mich an das was ich kenne und wo ich keine Veränderung erwarte.
Das sehe ich genauso. Deshalb bleibe ich - solange es sich um Programmierung für Windows und um Prototypen für andere Plattformen handelt - bei Delphi 2006 (kostenloses "Turbo-Delphi") ohne Unicode.

FPC - auch nie neuste svn-Version - kann auch ohne Uniocode.

Ich finde es völlig unverständlich, dass man Lazarus nicht auf Wunsch mit einer Option so übersetzen kann dass es (wie Delphi 2006) mit locale-abhängigen 8-Bit ANSI Strings arbeitet, statt in einem Stringtyp, der "ANSIString" heißt, statt ANSI-Code UTF8-Code zu erwarten.

-Michael
(P.S. und Du bist immer sauer, wenn ich genau darüber schimpfe ?!?!?!?!? )

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Fehler mit Stringkonvertierung

Beitrag von Michl »

mse hat geschrieben:Vermutlich besser UnicodeString.
Nach geschätzen 50 verschiedenen Varianten und Tests, verschiedener Stringtypen und Auswertungen ist UnicodeString der Typ, mit dem ich mein Anfangsproblem gelöst habe (habe damit keine Konvertierungsprobleme) , danke für den Tip!

Zuerst wandle ich UTF8 nach Unicode um, dann teste ich auf "Char", wenn negativ teste ich noch auf "ÄÖÜäöüß", alles Andere wird gelöscht, dann Umwandlung nach UTF8. Das Ausgangsproblem ist damit für mich erstmal gelöst.

Die Frage, warum UTF8toAnsi und dann AnsiToUTF8 einen abweichenden String zum Ausgangsstring liefert, bleibt. Das liegt aber evtl. an meiner FPC-Trunc-Version...

Nochmals danke an alle Helfer!!!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

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

Re: Fehler mit Stringkonvertierung

Beitrag von theo »

mschnell hat geschrieben: (P.S. und Du bist immer sauer, wenn ich genau darüber schimpfe ?!?!?!?!? )
Du jammerst grundsätzlich immer über Unicode ohne jemals etwas davon verstehen zu wollen.
Wenn du 2% der Zeit, die du mit deinen halbgaren Beiträgen über das Thema verschwendet hast, für die Beschäftigung mit der Materie investiert hättest, wäre dein Problem gelöst.

Ich habe kein Problem mit UTF-8. Den Rest umschiffe ich, solange es noch in Entwicklung ist.
Ich beklage mich nicht.

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

Re: Fehler mit Stringkonvertierung

Beitrag von theo »

Michl hat geschrieben: Die Frage, warum UTF8toAnsi und dann AnsiToUTF8 einen abweichenden String zum Ausgangsstring liefert, bleibt. Das liegt aber evtl. an meiner FPC-Trunc-Version...
Ich empfehle, sich mit Unicode (UTF.-8, UTF.-16 etc.) etwas auseinanderzusetzen.
Es eignet sich nicht für den Versuch & Irrtum Ansatz. Manchmal scheint es nur zu funktionieren, und dann fliegt man wieder auf die Nase.
Mein Tipp: Besser kurz die Grundlagen checken, als rätseln und sich ärgern.

BeniBela
Beiträge: 321
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: Fehler mit Stringkonvertierung

Beitrag von BeniBela »

mse hat geschrieben: Vermutlich besser UnicodeString. WideString auf Windows ist nicht Referenz-gezählter OLE-String.

Weder noch, beides ist Schrott.

UTF-16 sollte niemals verwendet werden,

Wenn man denkt das sei einfacher als utf-8, verliert man alle Zeichen nach U+10000

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: Fehler mit Stringkonvertierung

Beitrag von mse »

mschnell hat geschrieben:Deshalb bleibe ich - solange es sich um Programmierung für Windows und um Prototypen für andere Plattformen handelt - bei Delphi 2006 (kostenloses "Turbo-Delphi") ohne Unicode.
Da liegst du falsch, bereits Delphi 7 und Kylix 3 "können Unicode", der entsprechende Stringtyp dazu ist WideString. Bei Kylix 3 ist WideString identisch zum heutigen UnicodeString. Für Windows kam später die Referenz-gezählte Variante UnicodeString hinzu.
Auch du beziehst dich vermutlich auf den meiner Meinung nach unnötigen und für die FPC gesamt performance vermutlich sogar schädlichen "codepage aware AnsiString".

@BeniBela:
Deine Behauptung darf nicht unwidersprochen bleiben, sie ist unsinnig und falsch. Ich werde hier aber nicht weiter darauf eingehen.

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: Fehler mit Stringkonvertierung

Beitrag von mschnell »

theo hat geschrieben:... wäre dein Problem gelöst.
Wie schon wiederholt gesagt, habe ich gar kein Problem, das ich lösen müsste. Ich bin nur an der Optimierung der Lazarus/fpc- Tools interessiert.

-Michael

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: Fehler mit Stringkonvertierung

Beitrag von mschnell »

mse hat geschrieben:Da liegst du falsch, bereits Delphi 7 und Kylix 3 "können Unicode", ...
OK. Da habe ich mich mal wieder falsch ausgedrückt.

Was ich meinte war, dass Delphi 2006 mich nicht dazu zwingt, Unicode zu verwenden. Da ich bisher noch nie in die Verlegenheit gekommen bin Unicode praktisch einsetzten zu wollen, habe ich mich um die diesbezüglichen zusätzlichen Möglichkeiten nicht gekümmert. Das aktuelle Lazarus erzwingt dagegen den Einsatz von UTF8. Dadurch muss ich mich um Unicode kümmern obwohl ich das zwar gerne theoretisch, nicht aber bei der Realisation jedes kleinen Projektchens tun möchte.
mse hat geschrieben:Auch du beziehst dich vermutlich auf den meiner Meinung nach unnötigen und für die FPC gesamt performance vermutlich sogar schädlichen "codepage aware AnsiString".
Nein. Im Gegenteil (Die Lazarus API verwendet da aktuell ja nicht (vermutlich aber in zukünftigen Versionen, womit Theos Argument, dass er sich nicht immer wieder auf neue Varianten einstellen will, sehr verständlich ist), sondern UTF8).

Nach meinen diesbezüglichen Recherchen sind die "codepage aware String" vermutlich selbst dann (und nur dann) nur vernachlässigbar Performance-schädlich, wenn man sie in einer weit über Delphi XE hinausgehenden Form implementiert, nämlich so, dass (zusätzlich zu den durch die Typ-Definition in der Codierung festgelegten String-Typen) auch ein vollständig automatisierter voll dynamischer String Typ integriert wird, und z.B. bei allen TStrings Abkömmlingen wie TStringlist etc eingesetzt wird.

Meiner Ansicht nach ist das die vielversprechendste (anwenderfreundliche und umfassend einsetzbare) Methode, Unicode (und beliebige andere Codierungs Schemata) in der Sprache zu unterstützen.

Wenn Du tatsächlich einen neuen Compiler und die RTL dafür baust, könntest Du das möglicherweise in Betracht ziehen. (Mein Unterstützung dabei ist Dir sicher :D .)

-Michael
Zuletzt geändert von mschnell am So 27. Okt 2013, 09:27, insgesamt 2-mal geändert.

Antworten