 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
kilix
Anmeldungsdatum: 05.02.2022 Beiträge: 175
|
Verfasst am: 17.03.2022, 18:24 Titel: Problem mit Umlauten |
|
|
Nachdem alles was ich bisher programmiert habe - mit eurer großen Hilfe - funktioniert habe ich das nächste Problem zu dem ich bisher nichts wirklich brauchbares gefunden habe:
ich lese Date aus CSV-Dateien ein. In diesen Daten gibt es ein Fülle von namen und nicht wenige davon enthalten Umlaute.
Nun habe ich in diesen Thread
https://forum.qbasic.at/viewtopic.php?t=4652&highlight=umlaute
eine Funktion zur Konvertierung der Unlaute gefunden und dazu ein kleines Programm geschrieben mit dem ich ein Wort eingeben kann und das den/die Umlaute in diesem Wort konvertieren soll. Das macht es auch aber nicht so wie man es erwartet, nämlich z.B. Müller wird zu M?ller.
Irgendwie scheint das mit den Zeichencodes in DOS bzw Windows zu tun zu haben aber wie sich das verhält weiß ich nicht. Hier ist das Programm mit der abgekupferten Funktion:
Code: |
DECLARE FUNCTION uANSI2ASCII (ConvertString AS STRING) AS STRING
DIM AS STRING t
INPUT "Text eingeben: ", t
PRINT uANSI2ASCII (t)
getkey
FUNCTION uANSI2ASCII (ConvertString AS STRING) AS STRING
DIM AS STRING OutString=ConvertString
Static As UByte AscAnsDat(128)={ _
63, 63, 39, 159, 34, 46, 197, 206, 94, 37, 83, 60, 79, 63, 63, 63, _
90, 39, 39, 34, 34, 7, 45, 45, 126, 84, 115, 62, 111, 63, 122, 89, _
255, 173, 189, 156, 207, 190, 221, 145, 149, 184, 166, 174, 170, 240, 169, 238, _
248, 241, 253, 252, 239, 230, 244, 250, 247, 251, 167, 175, 172, 171, 243, 168, _
183, 181, 182, 199, 142, 143, 146, 128, 212, 144, 210, 211, 222, 214, 215, 216, _
209, 165, 227, 224, 226, 229, 153, 158, 157, 235, 233, 234, 154, 237, 232, 160, _
225, 133, 131, 198, 132, 134, 145, 135, 138, 130, 136, 137, 141, 161, 140, 139, _
208, 164, 149, 162, 147, 228, 148, 246, 155, 151, 163, 150, 129, 236, 231, 152}
FOR i AS INTEGER=0 TO LEN(OutString)-1
If OutString[i]>127 Then OutString[i]=AscAnsDat(OutString[i]-128)
NEXT i
RETURN OutString
END FUNCTION
|
Bitte wie schreibt man den Code in ein eigenes Fenster, dachte das geht mit [Code]? _________________ Grüße
kilix |
|
Nach oben |
|
 |
kilix
Anmeldungsdatum: 05.02.2022 Beiträge: 175
|
Verfasst am: 17.03.2022, 18:42 Titel: |
|
|
Ich denke, ich hab gefunden was ich suche - im FB Tutorial. Nachdem ich Windows10 verwende habe ich
#INCLUDE "windows.bi"
EDIT: habe Text gestrichen, war ein Fehler von mir. Damit ist diese Frage geklärt!!  _________________ Grüße
kilix |
|
Nach oben |
|
 |
kilix
Anmeldungsdatum: 05.02.2022 Beiträge: 175
|
Verfasst am: 17.03.2022, 18:57 Titel: |
|
|
Da habe ich mich leider zu früh gefreut den in meinem Programm werden die Umlaute zwar anders aber wieder nicht richtig übersetzt.
Ich habe am Beginn des Programmes das Include geschrieben:
#INCLUDE "windows.bi"
und in den Zeilen vor dem Print-Befehl:
CharToOem Sas2a, Sas2a
CharToOem Sas3a, Sas3a
aber das ist offenbar so nicht richtig _________________ Grüße
kilix |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4688 Wohnort: ~/
|
Verfasst am: 17.03.2022, 19:23 Titel: |
|
|
Das Problem ist halt immer die Frage, welche Zeichenkodierung wo verwendet wird. ANSI wird uns wahrscheinlich noch eine lange Zeit Kopfschmerzen bereiten.
Mit den Umwandlungsfunktionen der windows.bi kenne ich mich nicht großartig aus; vor allem bleibt das Problem, woran die richtige ANSI-Codepage erkannt werden soll bzw. ob die Funktion das überhaupt leisten kann/will. Ich würde auf jeden Fall erst einmal versuchen, als Quellstring und Zielstring verschiedene Variablen zu verwenden, da ich nicht ausschließen kann, dass sich der Lese- und Schreibvorgang sonst gegenseitig in die Quere kommt.
Sas2a usw. müssen auf jeden Fall laut WinAPI Pointer sein (also nicht der String selbst). Bei den FB-internen Strings ist das STRPTR(zeichenkette) (nicht *zeichenkette !) Allerdings muss dann der Zielstring vorher schon in ausreichender Länge definiert sein ... am besten gar kein STRING verwenden, sondern ZSTRING PTR.
Wenn du es per Hand machen willst - abgesehen davon, dass man natürlich versuchen kann, die Codierung über das erzeugende Programm herauszufinden:
Mal ganz grundsätzlich könntest du einen eingelesenen String in seine einzelnen Zeichennummern zerlegen, um herauszufinden, welcher Buchstabe wie codiert wurde. ASCII-Zeichen sind einheitlich, interessant sind daher nur die Nummern > 127.
Code: | FOR i AS INTEGER = 0 TO LEN(nachname)-1
PRINT nachname[i]
NEXT
|
In deinem Fall "Müller" ist dann interessant, welche Nummer der zweite Buchstabe hat. Außer der Text ist UTF-codiert; dann ist es per Hand komplizierter (aber dafür gibt es solche Umwandlungsfunktionen).
Nachteil ist, dass die so herausgefundenen Werte nur funktionieren, solange immer dieselbe ANSI-Codepage verwendet wurde. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Zuletzt bearbeitet von nemored am 17.03.2022, 19:27, insgesamt einmal bearbeitet |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4688 Wohnort: ~/
|
Verfasst am: 17.03.2022, 19:27 Titel: |
|
|
Zitat: | Bitte wie schreibt man den Code in ein eigenes Fenster, dachte das geht mit [Code]? |
Ja, an sich schon. War bei dir das Häckchen "BBCode in diesem Beitrag deaktivieren" abgewählt? _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
 |
kilix
Anmeldungsdatum: 05.02.2022 Beiträge: 175
|
Verfasst am: 17.03.2022, 19:45 Titel: |
|
|
Die zeichencodierung ist offenbar ein schwieriges Problem vorallem auch weil das auf jedem Computer anders sein kann wenn eine andere Codierung eingestellt ist.
Zu Beginn des Threads habe ich eine Funktion hereinkopiert die offenbar ASCII-Codes umwandelt. Ich kann nur nicht erkennen wie diese Zahlenkolonnen zu deuten sind.
Im Augenblick bin ich da ziemlich ratlos.
Edit: ja, BBCode war deaktiviert _________________ Grüße
kilix |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4688 Wohnort: ~/
|
Verfasst am: 17.03.2022, 20:29 Titel: |
|
|
Die gute Nachricht ist: FreeBASIC verwendet in der Konsole und im Grafikfenster zwar zwei verschiedene Codierungen, aber unabhängig vom Betriebssystem immer dieselben zwei(*). Die Codierung der eingelesenen Datei hängt davon ab, mit welchem Programm die Datei erstellt wurde; auch das ist dann in der Regel beim gleichen Programm immer gleich (wenn nicht der Benutzer die Möglichkeit nutzt, etwas anderes einzustellen).
Meine handgeschriebene Ersetzungsfunktion sieht so aus - der Eingabestring (in ersetzeUmlaute bei den einzelnen Aufrufen jeweils die linke CHR-Zeichenkette) ist dabei in UTF-8 und muss an die bei dir verwendete Formatierung angepasst werden. Der rechte CHR-Ausdruck ist dann das in FreeBASIC benötigte Zeichen im Grafikfenster.
Code: | function ersetzeZeichenkette(text as string, alt as string, neu as string) as string
dim z as uinteger, ret as string = text
do
z = instr(ret, alt)
if z = 0 then exit do
ret = left(ret, z-1) & neu & mid(ret, z+len(alt))
loop
return ret
end function
sub ersetzeUmlaute(byref text as string)
text = ersetzeZeichenkette(text, chr(195, 164), chr(132)) ' ä
text = ersetzeZeichenkette(text, chr(195, 182), chr(148)) ' ö
text = ersetzeZeichenkette(text, chr(195, 188), chr(129)) ' ü
text = ersetzeZeichenkette(text, chr(195, 132), chr(142)) ' Ä
text = ersetzeZeichenkette(text, chr(195, 150), chr(153)) ' Ö
text = ersetzeZeichenkette(text, chr(195, 156), chr(154)) ' Ü
text = ersetzeZeichenkette(text, chr(195, 159), chr(225)) ' ß
end sub |
(*) Disclaimer: Was die Konsole anzeigt, hängt wiederum von den Einstellungen der Konsole ab. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
 |
kilix
Anmeldungsdatum: 05.02.2022 Beiträge: 175
|
Verfasst am: 17.03.2022, 20:38 Titel: |
|
|
Super danke! Erkenne einige Codes wieder die ich mir schon aus der Konsole und einer ASCII-Tabelle herausgesucht habe! _________________ Grüße
kilix |
|
Nach oben |
|
 |
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1278 Wohnort: Ruhrpott
|
Verfasst am: 18.03.2022, 17:33 Titel: |
|
|
kilix hat Folgendes geschrieben: | Da habe ich mich leider zu früh gefreut den in meinem Programm werden die Umlaute zwar anders aber wieder nicht richtig übersetzt.
Ich habe am Beginn des Programmes das Include geschrieben:
#INCLUDE "windows.bi"
und in den Zeilen vor dem Print-Befehl:
CharToOem Sas2a, Sas2a
CharToOem Sas3a, Sas3a
aber das ist offenbar so nicht richtig | Sollte es aber eigentlich. Code: | #Include Once "windows.bi"
Dim As String text = "Müller"
? text
CharToOem(text,text)
? text
Sleep | stellt nach der Umwandlung den Umlaut korrekt dar, zumindest bei mir.
Welche Codepage hast du eingestellt (am DOS-Prompt "chcp" eingeben)? Sollte 850 oder 1252 sein.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
 |
kilix
Anmeldungsdatum: 05.02.2022 Beiträge: 175
|
Verfasst am: 18.03.2022, 17:52 Titel: |
|
|
ich verstehe es nicht. meine aktive DOS Codepage ist 850
ich habe dieses programm geschrieben:
Code: |
#Include Once "windows.bi"
DIM AS STRING text, MeinText
MeinText="ABCdefÄÖÜäöüéÉ"
CharToOem MeinText, MeinText
INPUT "Text eingeben: ", text
CharToOem text, text
print Meintext
print text
GETKEY
|
MeinText wird richtig wiedergegeben aber der eingegeben text nicht. Da kommt M_ller statt Müller.
Das kann doch nur etwas mit dem INPUT zu tun haben? _________________ Grüße
kilix |
|
Nach oben |
|
 |
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1278 Wohnort: Ruhrpott
|
Verfasst am: 18.03.2022, 18:59 Titel: |
|
|
kilix hat Folgendes geschrieben: | Das kann doch nur etwas mit dem INPUT zu tun haben? | Irgendwo im Hinterkopf klingelt da was bei mir. Eingabe und Ausgabe haben unterschiedliche Codepages. Aber die Tastatureingabe ist -soweit ich mich erinnere- noch einmal etwas anderes.
Frag mich nicht warum, aber das hier funktioniert (zumindest bei mir): Code: | #Include Once "windows.bi"
Dim As String t
Input "Text eingeben: ", t
OemToChar(t,t)
CharToOem(t,t)
? t
Sleep
|
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
 |
kilix
Anmeldungsdatum: 05.02.2022 Beiträge: 175
|
Verfasst am: 18.03.2022, 19:09 Titel: |
|
|
Super, danke! Ja das hat funktioniert!!!  _________________ Grüße
kilix |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4688 Wohnort: ~/
|
Verfasst am: 18.03.2022, 19:21 Titel: |
|
|
Ich glaube auch nicht, dass das Problem in der Codepage der Ausgabe liegt, sondern in der Codepage der Eingabedatei.
edit: OK, hat sich wohl erledigt - um so besser. Ignoriert diesen Beitrag.  _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
 |
kilix
Anmeldungsdatum: 05.02.2022 Beiträge: 175
|
Verfasst am: 18.03.2022, 19:31 Titel: |
|
|
ja, danke, ich wußte nicht, dass es da Unterschiede gibt!
Aber jetzt ist es klar, ich danke euch! _________________ Grüße
kilix |
|
Nach oben |
|
 |
kilix
Anmeldungsdatum: 05.02.2022 Beiträge: 175
|
Verfasst am: 18.03.2022, 22:26 Titel: |
|
|
ich habe den Code von grindstone, der im Test funktioniert hat:
#Include Once "windows.bi" usw.
in ein Programm eingebaut, das Daten die zuvor aus einer CSV-Datei in eine Random-Datei übertragen wurden in der Konsole listet. Das hat wider Erwartung nicht funktioniert.
Dann habe ich auf die Funktion
ersetzeZeichenkette (von nemored, siehe frühere Antwort weiter oben)
geändert und das hat jetzt funktioniert.
Der Unterschied dieser Liste zu dem vorgenannten Test ist,
-dass im Test ein im Code gespeicherter Text und
- ein eingebener Text
beide mit Umlauten richtig dargestellt wurde.
Im Listprogramm wurde der Text aus einer Datei eingelesen. Scheinbar gibt es da auch noch Unterschiede aber letzlich hat es mit dem Code von nemored funktioniert. D.h. man muss, je nachdem woher der Text stammt andere Methoden für die Ersetzung von Umlauten anwenden. _________________ Grüße
kilix |
|
Nach oben |
|
 |
kilix
Anmeldungsdatum: 05.02.2022 Beiträge: 175
|
Verfasst am: 19.03.2022, 18:09 Titel: |
|
|
Das funktioniert richtig gut für diesen Fall! Ich habe noch 21 Ersetzungen ergänzt weil in den Spitznamen die verücktesten Sonderzeichen und alle möglichen Accents verwendet werden. Das hat für alle bis auf 2 Fälle gepasst. In diesen Fällen ist vor dem Sonderzeichen eine Leerstelle. Ich habe es mit chr(000) und chr(032) probiert aber es muss sich um ein anderes nicht druckbares Zeichen handeln. Aber das Sonderzeichen konnte ich (wie es sein sollte) o mit Accent grave umwandeln. Der einzige Schönheitsfehler ist die Leerstelle vor dem o die eigentlich nicht hingehört aber damit kann ich in diesem Fall leben.
So sieht die SUB jetzt aus:
Code: |
sub ersetzeUmlaute(byref text as string)
text = ersetzeZeichenkette(text, chr(195, 164), chr(132)) ' ä
text = ersetzeZeichenkette(text, chr(195, 182), chr(148)) ' ö
text = ersetzeZeichenkette(text, chr(195, 188), chr(129)) ' ü
text = ersetzeZeichenkette(text, chr(195, 132), chr(142)) ' Ä
text = ersetzeZeichenkette(text, chr(195, 150), chr(153)) ' Ö
text = ersetzeZeichenkette(text, chr(195, 156), chr(154)) ' Ü
text = ersetzeZeichenkette(text, chr(195, 159), chr(225)) ' ß
text = ersetzeZeichenkette(text, chr(195, 161), chr(133)) ' a mit accenr grave
text = ersetzeZeichenkette(text, chr(195, 165), chr(133)) ' a mit accenr grave
text = ersetzeZeichenkette(text, chr(195, 162), chr(131)) ' a mit Accent circonflex
text = ersetzeZeichenkette(text, chr(195, 169), chr(130)) ' e mit Accent aigu
text = ersetzeZeichenkette(text, chr(195, 168), chr(138)) ' e mit Accent grave
text = ersetzeZeichenkette(text, chr(195, 170), chr(136)) ' e mit Accent circonflex
text = ersetzeZeichenkette(text, chr(195, 173), chr(161)) ' i mit Accent aigu
text = ersetzeZeichenkette(text, chr(195, 174), chr(140)) ' i mit Accent circonflex
text = ersetzeZeichenkette(text, chr(195, 179), chr(162)) ' o mit Accent aigu
text = ersetzeZeichenkette(text, chr(178), chr(149)) ' o mit Accent grave
text = ersetzeZeichenkette(text, chr(180), chr(147)) ' o mit Accent circonflex
text = ersetzeZeichenkette(text, chr(199, 146), chr(208)) ' o mit Tilde?
text = ersetzeZeichenkette(text, chr(195, 186), chr(163)) ' u mit Accent aigu
text = ersetzeZeichenkette(text, chr(195, 177), chr(164)) ' n mit Tilde
text = ersetzeZeichenkette(text, chr(194, 187), chr(175)) ' kleine spitze Klammer zu
text = ersetzeZeichenkette(text, chr(194, 171), chr(174)) ' kleine spitze Klammer auf
text = ersetzeZeichenkette(text, chr(177), chr(176)) ' kleine spitze Klammer auf
text = ersetzeZeichenkette(text, chr(194, 182), chr(244)) ' verkehrtes P
text = ersetzeZeichenkette(text, chr(194, 183), chr(240)) ' kleines Minus
text = ersetzeZeichenkette(text, chr(194, 178), chr(253)) ' ²
text = ersetzeZeichenkette(text, chr(194, 167), chr(021)) ' §
text = ersetzeZeichenkette(text, chr(34, 34), chr(34)) ' "
text = ersetzeZeichenkette(text, chr(195), chr(000)) ' Leerstring
end sub
|
_________________ Grüße
kilix |
|
Nach oben |
|
 |
HorstD
Anmeldungsdatum: 01.11.2007 Beiträge: 110
|
Verfasst am: 20.03.2022, 17:45 Titel: |
|
|
Code: | text = ersetzeZeichenkette(text, chr(195), chr(000)) ' Leerstring |
Code: | text = ersetzeZeichenkette(text, chr(195), "") ' Leerstring |
|
|
Nach oben |
|
 |
kilix
Anmeldungsdatum: 05.02.2022 Beiträge: 175
|
Verfasst am: 25.06.2022, 13:22 Titel: |
|
|
Hallo!
habe weiter an meinen Programmen gearbeitet, verwende nur jetzt im Sommer weniger Zeit dafür.
Nun habe ich wieder ein Problem mit Umlauten:
1) habe ausgewählte Daten von einer Binary-Datei in einen Array gespeichert
2) der Array ARR(x) enthält in allen Sätzen einen String (Stringaddition der ausgewählten Felder)
3) diese Felder werden mit Left, Mid, Right extrahiert und in der Console gelistet. Dabei werden Umlaute falsch dargestellt.
4) ich habe nun versucht diese Umlaute zu übersetzen. Dazu habe ich der Reihe nach die in diesem Thread gelisteten Möglichkeiten versucht.
Ergebnis: jede Funktion zeigt ein anderes falsches Ergebnis. Ich versuchte auch sowohl beim in die Tabelle speichern als auch beim lesen der Tabelle umzuwandeln, aber das funktioniert auch nicht. Dazu habe ich beim Speichern in die Tabelle die Funktion "ersetzeUmlaute" verwendet. Das funktioniert immer wenn ich Daten aus einer Datei einlese. Für das Auslesen aus der Tabelle habe ich "CharToOem" verwendet ( wie für Texte die ich im Programm verwende). Leider alles ohne Erfolg!
Auch die in diesem Thread von mir ganz oben verwendete Funktion "uANSI2ASCII" hat nichts gebracht.
Gibt es da noch mehr Möglichkeiten?
EDIT: Problem gelöst, war Fehler im Code! _________________ Grüße
kilix |
|
Nach oben |
|
 |
hhr
Anmeldungsdatum: 15.07.2020 Beiträge: 111
|
Verfasst am: 25.06.2022, 18:48 Titel: |
|
|
Manchmal ist Wstr nützlich:
Code: | Dim As String s
s = "ÄÖÜäöüáàâéèêµ²³€"
Print s
Print
Print Wstr(s)
Print
Print
s = "¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäå"
Print s
Print
Print Wstr(s)
Print
Print
Print "Taste drücken"
Print Wstr("Taste drücken")
Sleep |
|
|
Nach oben |
|
 |
kilix
Anmeldungsdatum: 05.02.2022 Beiträge: 175
|
Verfasst am: 25.06.2022, 19:33 Titel: |
|
|
Danke!
Mein Problem ist zwar gelöst aber diese Lösung sieht sehr interessant aus - habe sie in meine Sammlung, auf die ich immer wieder zurückkomme, gespeichert.
Möglicherweise habe ich schon eine Verwendung dafpr !? _________________ Grüße
kilix |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|