[GELÖST] Dreh mich im Kreis mit 'ß'...
[GELÖST] Dreh mich im Kreis mit 'ß'...
Hallo,
vielleicht kann mir jemand helfen...sitze seit einiger Zeit an dem Problem...
Ich habe jetzt einiges zum Thema UTF8 / Ansi Konvertierung gelesen aber ich dreh mich hier im Kreis...
Aus eine CSV Datei (ANSI) lese ich eine Textfeld ein. Beim Einlesen habe ich folgenden Text in der String Variable drin stehen: ...Roter Strau'#157' (Sollte Roter Strauß stehen)
Dieses Feld soll über eine StringList in eine Text Datei geschrieben werden
Wenn ich ANSIToUTF8 benutze habe ich: Roter Strau�
Wenn ich UTF8ToAnsi benutze habe ich: Roter Strau?
Irgendwie bekomme ich es nicht hin das das 'ß' entweder in die Variable richtig eingelesen wird oder aber in der Ausgabe korrekt geschrieben wird.
Oder muss ich tatsächlich den String scannen und das Zeichen durch 'ss' ersetzen???
Noch zur Info:
OS Win7 / Win10, Lazarus 1.6.2, FPC 3.02, keine speziellen Compiler Schalter gesetzt.
PS. benutze die Unit csvreadwrite zum einlesen des Textes
vielleicht kann mir jemand helfen...sitze seit einiger Zeit an dem Problem...
Ich habe jetzt einiges zum Thema UTF8 / Ansi Konvertierung gelesen aber ich dreh mich hier im Kreis...
Aus eine CSV Datei (ANSI) lese ich eine Textfeld ein. Beim Einlesen habe ich folgenden Text in der String Variable drin stehen: ...Roter Strau'#157' (Sollte Roter Strauß stehen)
Dieses Feld soll über eine StringList in eine Text Datei geschrieben werden
Wenn ich ANSIToUTF8 benutze habe ich: Roter Strau�
Wenn ich UTF8ToAnsi benutze habe ich: Roter Strau?
Irgendwie bekomme ich es nicht hin das das 'ß' entweder in die Variable richtig eingelesen wird oder aber in der Ausgabe korrekt geschrieben wird.
Oder muss ich tatsächlich den String scannen und das Zeichen durch 'ss' ersetzen???
Noch zur Info:
OS Win7 / Win10, Lazarus 1.6.2, FPC 3.02, keine speziellen Compiler Schalter gesetzt.
PS. benutze die Unit csvreadwrite zum einlesen des Textes
Zuletzt geändert von BitRausch am Sa 30. Sep 2017, 12:52, insgesamt 1-mal geändert.
-
- Beiträge: 1224
- Registriert: So 20. Mär 2016, 22:14
- OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
- CPU-Target: Raspberry Pi 3
Re: Dreh mich im Kreis mit 'ß'...
Und wenn Du gar nicht konvertierst?
Unter Windows sollte FPC einen String erstmal als Ansistring ansehen, sofern nichts anderes angegeben.
Unter Windows sollte FPC einen String erstmal als Ansistring ansehen, sofern nichts anderes angegeben.
Re: Dreh mich im Kreis mit 'ß'...
Hi Timm - danke für deine Antwort.
Ohne Konvertierung bekomme ich als Ausgabe 'Roter Strau '
Also ohne das ß am ende ...
Vielleicht sollte ich noch erwähnen das ich bei der Ausgabe einen String aus verschiedenen Felder erzeugen die ich in einer Stringlist hinzufüge um sie dann mit SaveToFile weg zuschreiben.
Die Felder werden mit PadRight formatiert
Diesem Fall s:= ...+...+PadRight(Beschreibung,65)
wobei Beschreibung die Feldvariable vom typ String ist..
Ohne Konvertierung bekomme ich als Ausgabe 'Roter Strau '
Also ohne das ß am ende ...
Vielleicht sollte ich noch erwähnen das ich bei der Ausgabe einen String aus verschiedenen Felder erzeugen die ich in einer Stringlist hinzufüge um sie dann mit SaveToFile weg zuschreiben.
Die Felder werden mit PadRight formatiert
Diesem Fall s:= ...+...+PadRight(Beschreibung,65)
wobei Beschreibung die Feldvariable vom typ String ist..
Re: Dreh mich im Kreis mit 'ß'...
Nein, konvertieren auf irgendeine Art und Weise muss man schon, denn die Strings in der Daten sind wahrscheinlich für die Codeseite 1252 codiert, wir brauchen in Lazarus aber UTF8. Das geht seit FPC3.0 automatisch, wenn man alles richtig macht - siehe dazu http://wiki.freepascal.org/Unicode_Support_in_Lazarus. Am veständlichsten und einleuchtendsten sind in meinen Augen aber immer noch die expliziten Konvertierungsfunktionen. Nur muss man dazu wissen, dass seit fpc 3.0 funktionieren die "klassischen" Routinen AnsiToUtf8 und SysToUtf8 nicht mehr funktioniereen - das ist nach Einführung der neuen Strings so gewollt (wobei ich nie verstehe, ob das wirklich sein musste). Nimm stattdessen CP1252ToUTF8() aus lconvencoding oder WinCPToUTF8() aus LazUtf8. Falls du eine Zwischenvariable für den vom csvParser zurückgegebenen String verwenden willst, deklariere den aufnehmenden String am besten als RawBytestring, damit FPC nicht hier schon eine Konvertierung durchführt.
Code: Alles auswählen
procedure TForm1.Button1Click(Sender: TObject);
var
csv: TCSVParser;
ms: TMemoryStream;
begin
csv := TCSVParser.Create;
try
ms := TMemoryStream.Create;
try
ms.LoadfromFile(FILE_NAME);
csv.Delimiter := #9;
csv.SetSource(ms);
csv.ResetParser;
while csv.ParseNextCell do
Memo1.Lines.Add(CP1252ToUtf8(csv.CurrentCellText)); // <--- hier
finally
ms.Free;
end;
finally
csv.Free;
end;
end;
Re: Dreh mich im Kreis mit 'ß'...
Hier stecken einige Stolperfallen drin...BitRausch hat geschrieben:Hi Timm - danke für deine Antwort.
Ohne Konvertierung bekomme ich als Ausgabe 'Roter Strau '
Also ohne das ß am ende ...
Vielleicht sollte ich noch erwähnen das ich bei der Ausgabe einen String aus verschiedenen Felder erzeugen die ich in einer Stringlist hinzufüge um sie dann mit SaveToFile weg zuschreiben.
Die Felder werden mit PadRight formatiert
Diesem Fall s:= ...+...+PadRight(Beschreibung,65)
wobei Beschreibung die Feldvariable vom typ String ist..
SaveToFile: Wenn du vorher eine Konvertierung der Stringcodierung vorgenommen hast, sind die Strings, die du in die Datei schreibst UTF8. Ich weiß nicht, ob das vorkommen kann, aber deine Routine, die die Dateien eingelesen hat, darfst du dann auf diese Datei nicht anwenden, denn es war ja angenommen, dass die Strings die Codeseite 1252 haben. Ganz schön kompliziert... Schreibe die Datei als UTF8 mit BOM, dann ist klar, dass es eine UTF8-Datei ist, du musst das halt beim Einlesen prüfen. Oder konvertiere alles zurück auf ANSI und schreibe wieder eine ANSI-Datei mit Codepage 1252 (obwohl ich das heute nicht mehr machen würde, ANSI sollte allmählich verschwinden).
PadRight(Beschreibung, 65): Ich nehme an, dass das Feld nun UTF8-kodiert ist. Wenn das feld den Text "Strauß" enthält, musst du beachten, dass dieser String 7 Byte lang ist (statt 6), weil das ß in UTF8-Kodierung zwei Byte umfasst.. Die Funktion PadRight(...,65) füllt auf insgesamt 65 Byte auf - das heißt, wenn du z.B. mit Schriftart Courier mehrere so erweiterte Felder untereinander ausgibst, wird dieses um 1 Zeichen zu kurz sein. Nimm stattdessen die Funktion UTF8PadRight, die die "wahren" Zeichen zählt (aber etwas langsamer ist).
Re: Dreh mich im Kreis mit 'ß'...
vielen Dank wp_xyz.
Habe gerade
CP1252ToUtf8 getestet:
Roter Strau
und mit WinCPToUTF8
Roter Strau'
das selbe Ergebnis..
Einlesen und Ausgabe sind unterschiedlich Listen
TFPGObjectList vs TStringList
mit UTF8PadRight fehlt mir weiterhin ein Zeichen...
Komisch finde ich das bei einem Text wie "Rosa Bl³ten" die anzahl stellen stimmen... auch wenn Umlaut nicht stimmt...
Ausgabe ist übrigens eine ANSI Datei. Bei der Stringliste benutze ich keine CodePage...
Wahnsinnig kompliziert das ganze
Edit: Ich nutze keine GUI Kontrollelemente zur Anzeige des Datensatzes...
Im Prinzip mach ich folgendes:
- Lesen eines CSV Datensatzes in ein TMyObject
- validieren des Datensatzes
- Add(TMyObject) zur TFPGObjectList
- Sortieren der Liste
- zusammenbauen eines Strings
- Add(s) to StringListe
- SaveToFile
Fast nur Stringoperationen/zuweisungen...
Habe gerade
CP1252ToUtf8 getestet:
Roter Strau
und mit WinCPToUTF8
Roter Strau'
das selbe Ergebnis..
Einlesen und Ausgabe sind unterschiedlich Listen
TFPGObjectList vs TStringList
genau das passiert mir gerade und zerschießt meinen fixen Satzaufbau in der Ausgabe...... wird dieses um 1 Zeichen zu kurz sein
mit UTF8PadRight fehlt mir weiterhin ein Zeichen...
Komisch finde ich das bei einem Text wie "Rosa Bl³ten" die anzahl stellen stimmen... auch wenn Umlaut nicht stimmt...
Ausgabe ist übrigens eine ANSI Datei. Bei der Stringliste benutze ich keine CodePage...
Wahnsinnig kompliziert das ganze
Edit: Ich nutze keine GUI Kontrollelemente zur Anzeige des Datensatzes...
Im Prinzip mach ich folgendes:
- Lesen eines CSV Datensatzes in ein TMyObject
- validieren des Datensatzes
- Add(TMyObject) zur TFPGObjectList
- Sortieren der Liste
- zusammenbauen eines Strings
- Add(s) to StringListe
- SaveToFile
Fast nur Stringoperationen/zuweisungen...
Re: Dreh mich im Kreis mit 'ß'...
vielleicht ist es einfacher Umlaute und das 'ß' im Feld zu ersetzen...
Gibt es eine Routine die Umlaute und das 'ß' einfach ersetzt bzw durch 'ae','ue','oe', 'ss' ersetzt ohne das ein Konvertierung UTF-8/Ansi notwendig wäre?
Gibt es eine Routine die Umlaute und das 'ß' einfach ersetzt bzw durch 'ae','ue','oe', 'ss' ersetzt ohne das ein Konvertierung UTF-8/Ansi notwendig wäre?
Re: Dreh mich im Kreis mit 'ß'...
... mich wundert auch das das 'ß' beim einlesen mit dem Code #157 im String angezeigt wird...
Das steht in der ASCII Tabelle für Ø
Das 'ß' hat den Code 225...
oder ist das nicht der ASCII Code??
Das steht in der ASCII Tabelle für Ø
Das 'ß' hat den Code 225...
oder ist das nicht der ASCII Code??
-
- Beiträge: 6915
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Dreh mich im Kreis mit 'ß'...
Etwas komisch ist, das ausgerechnet #157 für das ß steht. Was macht Excel mit der CSV-Datei ?Aus eine CSV Datei (ANSI) lese ich eine Textfeld ein. Beim Einlesen habe ich folgenden Text in der String Variable drin stehen: ...Roter Strau'#157' (Sollte Roter Strauß stehen)
Ich vermute mal, deine CSV wurde mit einem exotischen ASCII-Format abgespeichert.
Was spuckt dein Programm aus, wen du folgendes mit deinem String machst, nachdem er von der CSV-Datei eingelesen wurde ?
Code: Alles auswählen
const
s = 'Roter Strauß';
var
i: integer;
begin
for i := 1 to Length(s) do begin
Writeln(s[i], byte(s[i]): 6);
end;
end.
PS: Jetzt habe ich gerade was neues entdeckt, wen ich auf meiner CH-Tastatur [Alt-GR + s] drücke, kommt ein ß.

PS2: in der CT, die vor 2 Wochen erschienen ist, hat es einen grösseren Artikel, wieso wir so Theater mit den Umlauten haben.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
Re: Dreh mich im Kreis mit 'ß'...
Dann hast du ein reines FPC-Programm, ohne LCL? Und die Ausgabe geht auf die Konsole? Da ist alles nochmals anders...Edit: Ich nutze keine GUI Kontrollelemente zur Anzeige des Datensatzes...
Am besten wäre, die streichst dein Programm zu einer minimalen Demo zusammen, die nichts anderes macht, als die Datei zu laden und anzuzeigen, und lade alles (d.h. *.pas, *.lfm, *.lpr, *.lpi, sowie die Datei) in ein zip gepackt hier hoch.
-
- Beiträge: 6915
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Dreh mich im Kreis mit 'ß'...
Das spielt es dann auch wieder eine Rolle, die Konsolen können mit verschieden Codepages voreingestellt sein.Und die Ausgabe geht auf die Konsole? Da ist alles nochmals anders...
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
Re: Dreh mich im Kreis mit 'ß'...
Nein es ist kein Konsolenprogramm. Die Verarbeitung passiert quasi im Hintergrund. Der User wählt die einzulsenden Dateien aus und startet die Validierung/Konvertierung.
Wollte nur sagen das die Datensätze nicht über ein GUI Element angezeigt werden. Ich hatte gelesen das bei GUI Elementen es nochmal Besonderheiten für UTF-8/Ansi gibt...
Wollte nur sagen das die Datensätze nicht über ein GUI Element angezeigt werden. Ich hatte gelesen das bei GUI Elementen es nochmal Besonderheiten für UTF-8/Ansi gibt...
-
- Lazarusforum e. V.
- Beiträge: 999
- Registriert: Do 17. Apr 2008, 01:59
- OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
- CPU-Target: Intel i7-10750 64Bit
- Wohnort: Freiburg
Re: Dreh mich im Kreis mit 'ß'...
in ANSI CP 1252 ist 157 nicht definiert
157 0x9D undefined
Es wäre hilfreich, etwas über die Quelle der Datei zu erfahren. Kommt diese eventuell aus einem fremdsprachigen Programm?
157 0x9D undefined
Es wäre hilfreich, etwas über die Quelle der Datei zu erfahren. Kommt diese eventuell aus einem fremdsprachigen Programm?
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
Re: Dreh mich im Kreis mit 'ß'...
Sorry dass ich so dumm frage, aber wo ist dann das Problem? Wenn du die Strings weder in einem Gui-Control noch auf der Konsole anzeigst, wie willst du dann wissen, dass die Kodierung nicht stimmt?BitRausch hat geschrieben:Nein es ist kein Konsolenprogramm [...] Wollte nur sagen das die Datensätze nicht über ein GUI Element angezeigt werden.
Re: Dreh mich im Kreis mit 'ß'...
hmmm...
Ich vergleiche gerade die Excel Datei mit den CSV und Textdateien und sehe folgendes:
Was mir Auffällt ist das, egal ob der Inhalt mit korrektem Umlaut angezeigt wird oder nicht, die Satzlänge stimmt. Nur bei dem Feld wo das 'ß' am ende steht gibts das Problem...
Vielleicht tatsächlich ein Sonderzeichen in Excel?
Abgespeichert wird die Tabelle in Excel normal mit Dateityp CSV...
Ich werde mal das Feld in Excel leeren und Beschreibung neu eingebe ... mal schauen
Ich vergleiche gerade die Excel Datei mit den CSV und Textdateien und sehe folgendes:
Code: Alles auswählen
Excel: Excel CSV Nach Programmdurchlauf Satzalänge
Rosa Bl³ten Rosa Bl³ten Rosa Bl³ten OK
RoterStrau RoterStrau RoterStrau -1 Zeichen
Ölgemälde "Ölgemälde " "Ölgemälde " OK
Krüge Krüge Krüge OK
Klimagerät Klimagerät Klimagerät OK
Vielleicht tatsächlich ein Sonderzeichen in Excel?
Abgespeichert wird die Tabelle in Excel normal mit Dateityp CSV...
Ich werde mal das Feld in Excel leeren und Beschreibung neu eingebe ... mal schauen