CodePage-Umschaltung zwecks Beseitigung Ausgabeproblem



  • Hallo

    Ich kämpfe schon seit geraumer Zeit mit einem Character-Ausgabeproblem. Ich habe dazu auch zwei Beiträge dazu:

    ASCII-Problem in Japan?
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-133361.html

    CString Find mit 'x' oder "x"?
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-133363.html

    Aus beiden Diskussionen habe ich ein paar Erkenntnisse finden können, welche ich jetzt hier speziell Thematisieren will (Daher auch der neue Beitrag mit passender Überschrift):

    Vorgeschichte:
    Meine Applikation (VC++ 6.0 Dialog-App, MFC statisch gebunden, nicht Unicode compiliert) kann u.a. Dateien einlesen und den Inhalt daraus verarbeiten. Der Inhalt (Text) beinhaltet teilweise Sonderzeichen (ö, é etc.), liegt aber im Base64codierten format vor (also durckbare 6Bit-Asciizeichen).

    Das Öffnen funktioniert prima, doch auf einem Japanischen Windows funktioniert die Datenverarbeitung und die Datendarstellung nicht korrekt.

    Erkenntnis:
    Die Daten werden zeilweise mit CStdioFile::ReadString() gelesen und in ein CStringArray abgelegt.
    Beispieldatenzeile:

    Zeile1: 8000:Französisch|French|||;
    Zeile2: 8001:Olé|Olé|||;

    Das 'ö' (0xF6) und 'é' (0xE9) sind im erweiterten ASCII-Bereich. Diese Werte werden nun je nach Ländereinstellungen (MS Codepages) entsprechend interpretiert. Hier* funktioniert die Darstellung perfekt, weil 0xE9 mit dem Codepage Zeichensatz "Latin-1" bzw. Code# 1252 übereinstimmt.

    Wird nun das selbe exe-Programm in Japan ausgeführt, so werden diese Sonderzeichen anders interpretiert, weil dort eine andere Ländereinstellung bzw. die Codepage 932 aktiv ist.

    Problem 1:
    Obschon die Datenzeile auch in Japan richtig eingelesen wird, ist die Datendarstellung nicht richtig
    [cpp]
    CString str;
    stringEinlesen(str);
    // str beinhaltet nun die Daten für den String "Hello and olé-miau";

    [/cpp]
    Das 'é' wird durch ein anderes Ersetzt und das nachfolgende wird abgetrennt.Wenn ich nun den inhalt auslese (ob mit Debugger oder Messagebox) erscheint z.B. so etwas: "Hello and ol?miau". (Siehts man? 'é' wird ersetzt und das Nachfolgezeichen gelöscht!).

    str.GetLength(); // funktioniert und liefert den Wert 18
     str.Find('-');   // funkioniert NICHT!!!
    

    Lösungsansatz für Problem 1:
    Wenn nun die Datenzeilen ausgewertet werden müssen (z.b. ob im String 4x so ein Querbalken '|' vorhanden ist). Dann funktioniert das bei Zeile 1 (im Beispiel weiter oben), aber bei Z2 nicht mehr, weil dort durch das nichtanzeigen des nachfolgenden Zeichens nach dem Sonderzeichen die Anzahl der Balken nur noch 2 ist!

    Ich kann das Lösen, in dem ich vom CString die Daten einzeln auslese:

    // Bsp
    str // beinhaltet die Bytedaten für "hellé|World"
        // ausgabe wäre jetzt aber auf einem Jp-Windows "hell?World"
    int iPos = str.Find('|', 0); // gibt -1
    
    //aber so ginge es:
    BYTE byFind = '|';
    for(int i=0; i<str.GetLength(); i++){
      BYTE by = (BYTE) str.GetAt(i);
      if(by == byFind) AfxMessageBox("ok"}
    }
    

    // die <ok>-Message würde nun bei i-Position 5 erscheinen. Also stimmt die 'Suche'.

    PS: Ich habe 98 CString::Find() Methoden aufrufe 😮

    Problem 2:
    Die Daten werden vollständig in CStrings abgelegt, obschon diese nicht richtig angezeigt werden. Das funktioniert 100%ig.
    Aber wie kann man jetzt das 'é'Zeichen z.B. auch auf dem Jp-Windows darstellen?

    Einfach die Sonderzeichen-Darstellung dem Windows überlassen ist auch doof, denn anstatt "Französisch" steht dort jetzt vielleicht "Franz?isch". Habe auch gesehn, dass anstelle des Sonderzeichen ein Asiatisches steht (Nachfolgezeichen ist weg, weil diese Asia-Zeichen wohl 2Byte benötigen) Ok, man kann berechtigterweise Fragen, was der Japaner mit diesem Wort will, aber es geht eben generell um das Problem, weil teilweise auch anzuzeigende Produktenamen Sonderzeichen beinhalten.

    Lösungsansatz für Problem-2
    Ich stelle mir z.B. eine Mappingtabelle vor, wo man definiert, dass z.b. der Datewert von 'é' (0xE9) auf ein Unicode-Symbol zeigt.

    Hier stelle ich die Frage, wie soll so etwas gehen?

    Ein weiterer Ansatz ist das Umschalten der Codepage. Man stellt mittels der Methode 'setlocale' die Codepage auf dem Jp-Windows einfach in meinem Programm auf "English" oder so. Aber das geht nicht richtig! Habe keine richtige Ahnung, wie man diese Methode korrekt anwendet.

    Ich bin hier echt am Ende mit meinen Ideen. Wär toll wenn mir jemand aushelfen könnte!

    Ach ja, ich kann mittlerweile die Jp-Windows-Problematik auf meinem zweitrechner nachvollziehen. Habe auf meinem XP-PC alle erdenklichen Regionalal- & Spracheinstellungen auf Japanisch gestellt. Jetzt habe ich denselben Effekt wie die Japaner dort drüben. hehe.

    Das Programm in UNICODE compilieren kann ich JETZT definitv nicht mehr. Der Aufwand wäre zu unendlich.

    * hier: mit hier ist ein Windows-2000-PC mit Deutscher Sprache gemeint.



  • Ich vermute fast mal, dass das einfachste sein wird, Dein Programm mit UNICODE zu überstzen...
    Du kannst nicht Japanisch und Französisch gleichzeitg anzeigen, wenn Du es mit MBCS übersetzt hast.



  • Jochen Kalmbach schrieb:

    Ich vermute fast mal, dass das einfachste sein wird, Dein Programm mit UNICODE zu überstzen...
    Du kannst nicht Japanisch und Französisch gleichzeitg anzeigen, wenn Du es mit MBCS übersetzt hast.

    Ah sorry, ich habe vergessen zu erwähnen, dass sämtliche Ressourcen (Stringtables) auf English sind oder wenn man die Sprach-Dll hat noch auf Deutsch.

    Da meine Applikation also so oder so nur En od De unterstützt, reicht die Unterstützung der Latin-1 erweiterung vollkommen.

    Unicode-Compilierung kommt nicht in Frage, weil ich noch externe Klassen (solche die von codeproject etc. sind (jaja, natürlich freeware oder lizenzrechte angefragt) oder von anderen. Die Dfunktionen daraus benütze ich lediglich.).



  • Hast Du schon

    SetThreadLocale(MAKELANGID(0x0407, SUBLANG_DEFAULT));
    

    probiert? Hab gerade kein Jap-OS da...


Anmelden zum Antworten