[GELÖST] Dreh mich im Kreis mit 'ß'...

Für Fragen von Einsteigern und Programmieranfängern...

[GELÖST] Dreh mich im Kreis mit 'ß'...

Beitragvon BitRausch » 29. Sep 2017, 15:05 [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
Zuletzt geändert von BitRausch am 30. Sep 2017, 11:52, insgesamt 1-mal geändert.
BitRausch
 
Beiträge: 50
Registriert: 30. Mai 2017, 08:32

Beitragvon Timm Thaler » 29. Sep 2017, 15:32 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.
Timm Thaler
 
Beiträge: 431
Registriert: 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.6 FPC3.0.0, Raspbian Jessie Laz1.6 FPC3.0.0 | 
CPU-Target: Raspberry Pi 3
Nach oben

Beitragvon BitRausch » 29. Sep 2017, 15:49 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..
BitRausch
 
Beiträge: 50
Registriert: 30. Mai 2017, 08:32

Beitragvon wp_xyz » 29. Sep 2017, 15:53 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;
wp_xyz
 
Beiträge: 2251
Registriert: 8. Apr 2011, 08:01

Beitragvon wp_xyz » 29. Sep 2017, 16:05 Re: Dreh mich im Kreis mit 'ß'...

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..

Hier stecken einige Stolperfallen drin...

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).
wp_xyz
 
Beiträge: 2251
Registriert: 8. Apr 2011, 08:01

Beitragvon BitRausch » 29. Sep 2017, 16:35 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

... wird dieses um 1 Zeichen zu kurz sein

genau das passiert mir gerade und zerschießt meinen fixen Satzaufbau in der Ausgabe...

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...
BitRausch
 
Beiträge: 50
Registriert: 30. Mai 2017, 08:32

Beitragvon BitRausch » 29. Sep 2017, 16:52 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?
BitRausch
 
Beiträge: 50
Registriert: 30. Mai 2017, 08:32

Beitragvon BitRausch » 29. Sep 2017, 17:05 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??
BitRausch
 
Beiträge: 50
Registriert: 30. Mai 2017, 08:32

Beitragvon Mathias » 29. Sep 2017, 17:06 Re: Dreh mich im Kreis mit 'ß'...

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)

Etwas komisch ist, das ausgerechnet #157 für das ß steht. Was macht Excel mit der CSV-Datei ?
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 ß. :wink:
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 gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 3194
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon wp_xyz » 29. Sep 2017, 17:16 Re: Dreh mich im Kreis mit 'ß'...

Edit: Ich nutze keine GUI Kontrollelemente zur Anzeige des Datensatzes...

Dann hast du ein reines FPC-Programm, ohne LCL? Und die Ausgabe geht auf die Konsole? Da ist alles nochmals anders...

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.
wp_xyz
 
Beiträge: 2251
Registriert: 8. Apr 2011, 08:01

Beitragvon Mathias » 29. Sep 2017, 17:22 Re: Dreh mich im Kreis mit 'ß'...

Und die Ausgabe geht auf die Konsole? Da ist alles nochmals anders...

Das spielt es dann auch wieder eine Rolle, die Konsolen können mit verschieden Codepages voreingestellt sein.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 3194
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon BitRausch » 29. Sep 2017, 17:55 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...
BitRausch
 
Beiträge: 50
Registriert: 30. Mai 2017, 08:32

Beitragvon MacWomble » 29. Sep 2017, 18:18 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?
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
MacWomble
 
Beiträge: 366
Registriert: 17. Apr 2008, 00:59
Wohnort: Freiburg
OS, Lazarus, FPC: Mint 18.1 Cinnamon / CodeTyphon Generation V Plan 6.00 (FPC 3.1.1) | 
CPU-Target: 32/64 Nit
Nach oben

Beitragvon wp_xyz » 29. Sep 2017, 18:22 Re: Dreh mich im Kreis mit 'ß'...

BitRausch hat geschrieben:Nein es ist kein Konsolenprogramm [...] Wollte nur sagen das die Datensätze nicht über ein GUI Element angezeigt werden.

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?
wp_xyz
 
Beiträge: 2251
Registriert: 8. Apr 2011, 08:01

Beitragvon BitRausch » 29. Sep 2017, 18:37 Re: Dreh mich im Kreis mit 'ß'...

hmmm...
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


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
BitRausch
 
Beiträge: 50
Registriert: 30. Mai 2017, 08:32

» Weitere Beiträge siehe nächste Seite »
Nächste

Zurück zu Einsteigerfragen



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste

porpoises-institution
accuracy-worried