ASCII nach ANSI Anfängerfrage



  • Hallo,
    nachdem ich jetzt stundenlang hier im Forum gelesen habe und nicht weiterkomme, bitte ich euch, bei einem Problem zu helfen.
    Einer Funktion wird der Parameter "string& meinstring" übergeben. Dieser bekommt in der Funktion einen neuen Inhalt.

    char* neuerstring = "Text mit ASCII-Umlauten äöü";
    meinstring = neuerstring;

    Nun soll aber noch eine Konvertierung der Umlaute in die Windows-Zeichen stattfinden.

    In obigem Beispiel sind das die Character-Codes 132, 148 und 129. Die sollen zu 228, 246 und 252 werden.

    Wie macht man das am einfachsten? Ich benutze Visual C++ 2008 Express und habe bisher nur wenig C++ Erfahrungen.



  • @KleinesLicht
    ASCII kennt keine Umlaute. Das sind nur 7 Bit ( geht bis 127)

    Du schaust dir jedes Zeichen aus dem Quellstring an.

    Wenn es einer der besonderen Codes ist, schreibst du den Ersatz in den Zielstring.
    Sonst einfach den originalen Code.
    Wenn das Zeichen '\0' ist, bist du fertig.



  • @KleinesLicht Was du möchtest ist Codepage 437 nach Latin-1 bzw. Codepage 1252 konvertieren. Dazu kannst du entweder MultiByteToWideChar gefolgt von WideCharToMultiByte verwenden. Oder du bastelst dir eine eigene Übersetzungstabelle (Array) und transformierst dann Zeichen für Zeichen indem du einfach mit dem original Zeichencode in der Übersetzungstabelle nachschlägst.

    Oder, wenn du auf Schmerzen stehst, versuchst du iconv oder icu einzubinden.



  • @KleinesLicht

    Ich benutze Visual C++ 2008 Express

    Warum? Aktuell ist VS 2017.



  • @hustbaer Das war wohl der entscheidende Hinweis. (ich habe ewig mit OemToChar experimentiert.)
    Das ist jetzt meine Lösung:

    std::string neuerstring = meinstring;
    int num_chars = MultiByteToWideChar(437, MB_ERR_INVALID_CHARS, neuerstring.c_str(), neuerstring.length(), NULL, 0);
    std::wstring wstr;
    if (num_chars) {
      wstr.resize(num_chars);
      if (MultiByteToWideChar(437, MB_ERR_INVALID_CHARS, neuerstring.c_str(), neuerstring.length(), &wstr[0], num_chars)) {
        int size_needed = WideCharToMultiByte(1252, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
        std::string strTo( size_needed, 0 );
        WideCharToMultiByte(1252, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
        neuerstring = strTo;
      }
    }
    
    

    Oder ist das so nicht zu empfehlen?



  • @KleinesLicht
    Sieht jetzt nicht so verkehrt aus würde ich sagen.

    std::wstring wstr; würde ich noch ins if reinziehen, das brauchst du ausserhalb nicht. Und ich persönlich finde die Variablennamen nicht sehr sprechend.

    Ggf., falls du dir die ganzen Flags die man bei MultiByteToWideChar und WideCharToMultiByte mitgeben kann noch nicht durchgelesen hast, würde ich das machen. Ich hab z.B. noch nie MB_ERR_INVALID_CHARS verwendet - hatte noch keinen Fall wo ich mit nem Fehler abbrechen wollte statt nicht abbildbare Zeichen auf "?" abzubilden.

    Und: MB_ERR_INVALID_CHARS solltest du nur für MultiByteToWideChar verwenden. Bei WideCharToMultiByte heisst das entsprechende Flag WC_ERR_INVALID_CHARS. Mag sein dass die Werte hinter den beiden Konstanten identisch sind, das hab ich nie überprüft, aber sauber ist es auf jeden Fall nicht.



  • ps: 1252 ist die Default Codepage von deutschen und englischen Windows Versionen. Bist du sicher dass du Codepage 1252 willst, oder willst du vielleicht die Default Codepage des Systems auf dem das Programm gerade läuft?

    In dem Fall solltest du CP_ACP oder CP_THREAD_ACP als Codepage verwenden.



  • @KleinesLicht sagte in ASCII nach ANSI Anfängerfrage:

    (ich habe ewig mit OemToChar experimentiert.)

    Eigentlich, jetzt wo du es erwähnst... laut Doku sollte die Funktion genau das machen was du willst. Zumindest auf deutschen Windows Versionen, solange man die Default Codepage nicht verstellt hat.
    Was hattest du denn für Probleme damit?



  • @hustbaer Danke für Deine vielen ergänzenden Anmerkungen. Die Flags und CP_ACP sehe ich mir an. OemToChar... ich weiß auch nicht, vermutlich hat immer was mit den gefühlt tausend String-Typen nicht geklappt.


Anmelden zum Antworten