Problem mit Umlauten beim Einlesen mit ReadCharacter

Anfängerfragen zum Programmieren mit PureBasic.
Istvan42
Beiträge: 16
Registriert: 15.12.2019 16:59
Computerausstattung: MacOS Sonoma (M1), PureBasic 6.03 LTS (MacOS X - x64)

Problem mit Umlauten beim Einlesen mit ReadCharacter

Beitrag von Istvan42 »

Hallo zusammen,

ich stehe bei folgendem Problem auf dem Schlauch. In einer Textdatei steht folgender Inhalt:

Code: Alles auswählen

Das ist mein Test!
Für die Tür einen Öffner!
Die Datei ist als UTF-8 mit BOM erstellt worden. Wenn ich mittels ReadCharacter aus dieser Datei zeichenweise den Inhalt einlese und an einen String übergebe, dann erhalte ich folgende Ausgabe:

Code: Alles auswählen

??Das ist mein Test!
Fü?r die Tü?r einen Ö?ffner
Wenn ich den Inhalt zeilenweise mit ReadString einlese, dann ist das Ergebnis korrekt.

Hat jemand eine Erklärung dafür? Wie kann ich den Inhalt korrekt zeichenweise Einlesen und an einen String übergeben?

Hier mein Test-Code

Code: Alles auswählen

EnableExplicit

Enumeration 
    #Filehandler
EndEnumeration

Define sFilename.s, sContent.s, sUnicode.s, sFileString.s
Define iFilepos.i, iCharForm.i, iBOM.i
Define cFileChar.c

;iCharForm = #PB_Ascii
iCharForm = #PB_UTF8
;iCharForm = #PB_Unicode

sFilename = OpenFileRequester("Datei öffnen", "Test.txt", "Text-Datei (*txt) | *.txt", 0)

; lesen einzelner Zeichen
If ReadFile(#Filehandler, sFilename, iCharForm)
    ; Prüfen BOM (Byte Order Mark)  
    iBOM = ReadStringFormat(#Filehandler)
    Select iBOM
        Case #PB_Ascii
            MessageRequester("Format", "Ascii")
        Case #PB_UTF8
            MessageRequester("Format", "UTF8")
        Case #PB_Unicode
            MessageRequester("Format", "Unicode")
        Default
            MessageRequester("Format", "Was anderes")
    EndSelect
    While Eof(#Filehandler) = 0
        FileSeek(#Filehandler, iFilepos)
        cFileChar = ReadCharacter(#Filehandler, iCharForm)
        sContent + Chr(cFileChar)
        iFilepos + 1
    Wend
    MessageRequester("Content zeichenweise", sContent)
    ; lesen von Zeilen
    FileSeek(#Filehandler, 0) ; beginne am Anfang
    While Eof(#Filehandler) = 0
        sFileString + ReadString(#Filehandler, iCharForm) + Chr(13)
    Wend
    MessageRequester("Content zeilenweise", sFileString)
    CloseFile(#Filehandler)
Else
    MessageRequester("Fehler", "Beim lesen der Datei ist ein Fehler aufgetreten.")
EndIf
Gruß
Istvan
MacOS Sonoma (M1), PureBasic 6.03 LTS (MacOS X - x64)
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Problem mit Umlauten beim Einlesen mit ReadCharacter

Beitrag von mk-soft »

Bei UTF8 sind alle Zeichen über ASC 127 mit zwei oder mehr Byte kodiert.
Somit muss man, wenn man diese selber Zeichen für Zeichen liest, selber diese dekodieren.

Das macht aber keinen sinn, da diese PB selber machen kann

Es ist besser die Datei mit ReadString mit Format Info zu lesen, da die Umwandlung nach intern UNICODE automatisch erfolgt.

P.S. Hatte lange weile

Code: Alles auswählen

;-TOP 
; Read And Write TextFile by mk-soft, v1.02, 28.03.2020

EnableExplicit

Procedure ReadFileToList(FileName.s, List TextList.s()) ; Result Format (BOM)
  Protected file, format
  
  ClearList(TextList())
  
  file = ReadFile(#PB_Any, FileName)
  If file = 0
    Debug "Error Open File: " + FileName
    ProcedureReturn 0
  EndIf
  
  format = ReadStringFormat(file)
  If format = 0
    Debug "Error Read BOM: " + FileName
    CloseFile(file)
    ProcedureReturn 0
  EndIf
  
  While Not Eof(file)
    AddElement(TextList())
    TextList() = ReadString(file, format)
  Wend
  
  CloseFile(file)
  
  ProcedureReturn format
  
EndProcedure

; ----

Procedure WriteFileFromList(FileName.s, List TextList.s(), Format = #PB_UTF8) ; Result wrote lines
  Protected file, cnt
  
  If Format <> #PB_Ascii And Format <> #PB_UTF8 And Format <> #PB_Unicode
    Debug "Error BOM not supported: " + FileName
    ProcedureReturn 0
  EndIf
  
  file = CreateFile(#PB_Any, FileName, Format)
  If file = 0
    Debug "Error Create File: " + FileName
    ProcedureReturn 0
  EndIf
  
  If WriteStringFormat(file, Format) = 0
    Debug "Error Write BOM: " + FileName
    CloseFile(file)
    ProcedureReturn 0
  EndIf
    
  ForEach TextList()
    If WriteStringN(file, TextList()) = 0
      Debug "Error Write Line: " + FileName
      CloseFile(file)
      ProcedureReturn 0
    Else
      cnt + 1
    EndIf
  Next
  
  CloseFile(file)
  
  ProcedureReturn cnt
  
EndProcedure

; ****

Global NewList Text.s()

Define filename.s, bom, cnt

filename.s = OpenFileRequester("Open", "", "", 0)
If filename
  bom = ReadFileToList(filename, Text())
  Debug "BOM = " + bom
EndIf

ForEach Text()
  Debug Text()
Next

filename.s = SaveFileRequester("Save", filename + ".txt", "", 0)
If filename
  cnt = WriteFileFromList(filename, Text(), bom)
EndIf
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Istvan42
Beiträge: 16
Registriert: 15.12.2019 16:59
Computerausstattung: MacOS Sonoma (M1), PureBasic 6.03 LTS (MacOS X - x64)

Re: Problem mit Umlauten beim Einlesen mit ReadCharacter

Beitrag von Istvan42 »

Was ich aber nicht verstehe ist, dass man z.B. das Format #PB_UTF8 bei ReadCharacter() mitgeben kann. Die Rückgabe von ReadCharacter() ist vom speziellen Variablentyp 'Character' (.c) und PureBasic schaltet automatisch von 1 Byte auf 2 Bytes um, wenn Unicode aktiviert ist.
Grundsätzlich sollte es also gehen und vermutlich mache ich einen Denkfehler oder ich verstehe die Dokumentation nicht richtig.

Gruß
Istvan
MacOS Sonoma (M1), PureBasic 6.03 LTS (MacOS X - x64)
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Problem mit Umlauten beim Einlesen mit ReadCharacter

Beitrag von mk-soft »

Ein Gedankenfehler...

Du darfst nicht FileSeek verwenden. ReadCharacter setzt automatisch auf das nächste zeichen.

Code: Alles auswählen

While Eof(#Filehandler) = 0
        ;FileSeek(#Filehandler, iFilepos)
        cFileChar = ReadCharacter(#Filehandler, iCharForm)
        sContent + Chr(cFileChar)
        iFilepos + 1
    Wend
    
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Istvan42
Beiträge: 16
Registriert: 15.12.2019 16:59
Computerausstattung: MacOS Sonoma (M1), PureBasic 6.03 LTS (MacOS X - x64)

Re: Problem mit Umlauten beim Einlesen mit ReadCharacter

Beitrag von Istvan42 »

Bingo! Das war's! Wie soll man auch darauf kommen. In der Dokumentation steht dazu nichts.

Vielen Dank!


Istvan
MacOS Sonoma (M1), PureBasic 6.03 LTS (MacOS X - x64)
Antworten