Konsole und deutsche Umlaute



  • Mühsam nährt sich das Eichhörnchen. Das "Problem" Umlaute und Sonderzeichen ist so alt wie meine Tochter. Wie woanders kurz erwähnt bin ich ein Rookie was C++ angeht. Deshalb wühle ich mich mit einer Konsolenanwendung durch den Urschleim. Klappt auch recht gut bisher. Als Übungsobjekt habe ich mir eins meiner ältesten TurboPascal-Projekte vorgenommen, das ich mal 1988 geschrieben habe. Quelltext Fehlanzeige. Das Spiel ist eine Art Kniffel mit 6 Würfeln und läuft noch leidlich in einer 32-bit Konsolenumgebung.
    Die Neuauflage soll mit C++ erfolgen, später vielleicht auch mal Windowslike ebenfalls in C++. Noch aber ist die Konsolenversion in der Pipe und es gibt etlichen Text in Deutsch. Die einfachste Lösung wäre natürlich ..

    string zeile1 = "Der Knödel für Mädels";  // Gibt blöde Zeichen auf dem Screen
    string zeile2 = "Der Kn\x94del f\x81r M\x84dels"; // Könnte klappen, bringt aber Fehler weil Hexwert bei Knödel als \x94d interpretiert wird
    

    Als Provisorium habe ich daher eine Funktion zum Bereinigen des Strings geschrieben, die zunächst nur ä ö ü berücksichtigt:

    string cleanstrings(string pussi)
    {
    	int laenge = strlen(pussi.c_str())-1;
    	for (int i = 0; i <= laenge; ++i)
    	{
    		switch(pussi[i])
    	{
    		case 'ä' : pussi[i] = 0x84; 
    			break;
    		case 'ö' : pussi[i] = 0x94; 
    			break;
    		case 'ü' : pussi[i] = 0x81; 
    			break;
    		default : break;
    	}
    	}
    	return (pussi);
    };
    

    Ich werfe also den in reinem Deutsch definierten String rein und bekomme die Code-bereinigte Version wieder heraus - was auch gut klappt.
    Nun die Frage, ist das effizienter möglich oder kann ich mit diesem Workarround gut leben? Ich selbst könnte 🙂

    EDIT: Bei der Suche klickt man nicht immer den Link mit den besten Ergebnissen. Aber wenn ich vorher gesehen hätte ...: http://www.c-plusplus.net/forum/39326
    Sorry Sidewinder, habs jetzt erst gefunden, als ich was anderes suchte.



  • string zeile2 = "Der Kn\x94" "del f\x81r M\x84dels";
    




  • Danke für die beiden Ansätze. Die Windowsfunktion werde ich mir demnächst näher ansehen. Aber auch diese Art der String-Verkettung ohne dass man einen Operator wie "+" oder "&" verwendet ist ein kleines Aha-Erlebnis. Beim Lernen stößt man oft auf Quellen die String-Operationen auf Basis von C, C# und C++ eifrig mischen und damit erst mal ein kleines Chaos verursachen.



  • Du kannst für Zeichen auch die Oktal-Schreibweise nehmen.

    Es bleibt aber das Problem mit dem Encoding. Welche Codepage liegt für den Editor/Compiler und für die Konsole vor?

    Entweder auf Umlaute verzichten oder auf Unicode gehen.



  • Mein Gedanke war auch schon, ähnlich wie es bei HTML möglich ist:

    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    

    eine Art Compilerdirektive zu nutzen, die für die korrekte Umsetzung des Quelltextes in der Konsolenausgabe auf den Monitor sorgt.
    Andererseits will ich nicht zu faul sein, mir eine eigene Lösung einfallen zu lassen, die auf meinem gerade vorhandenen Wissen basiert. Wenn diese Lösung, so wie oben beschrieben existiert, kann man immer noch nach besseren Lösungen Ausschau halten.



  • Molse schrieb:

    Mein Gedanke war auch schon, ähnlich wie es bei HTML möglich ist:

    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    

    eine Art Compilerdirektive zu nutzen, die für die korrekte Umsetzung des Quelltextes in der Konsolenausgabe auf den Monitor sorgt.

    Wird wohl nicht gehen, da der compiler doch nicht wissen kann, welches Encoding die Konsole auf dem Zielgerät hat.



  • Um den Thread abzuschließen, ich habe die Funktion komplettiert, den Namen verkürzt und ein wenig auf Herz und Nieren getestet. Wohlwissend, dass es einfachere Lösungen gibt hier das Listing:

    string clnstr(string pussi)
    {
    	int laenge = strlen(pussi.c_str())-1;
    	for (int i = 0; i <= laenge; ++i)
    	{
    		switch(pussi[i])
    	{
    		case 'ä' : pussi[i] = 0x84; 
    			break;
    		case 'ö' : pussi[i] = 0x94; 
    			break;
    		case 'ü' : pussi[i] = 0x81; 
    			break;
    		case 'Ä' : pussi[i] = 0x8E; 
    			break;
    		case 'Ö' : pussi[i] = 0x99; 
    			break;
    		case 'Ü' : pussi[i] = 0x9A; 
    			break;
    		case 'ß' : pussi[i] = 0xE1; 
    			break;
    		default : break;
    	}
    	}
    	return (pussi);
    };
    

    Nutzen lässt es sich bspw. so:

    ...
    string zeile01 = "Übermäßiger Müßiggang könnte mäßig erfolgreich sein!"
    string zeile02 = "Knödel für Mädels und Männer!"
    ...
    
    int main()
    ...
    cout << clnstr(zeile01) << endl;
    cout << clnstr(zeile02) << endl;
    ...
    

    Thema erledigt 🕶



  • Molse schrieb:

    int laenge = strlen(pussi.c_str())-1;
    

    ??????
    http://en.cppreference.com/w/cpp/string/basic_string/size



  • asfdlol schrieb:

    Molse schrieb:

    int laenge = strlen(pussi.c_str())-1;
    

    ??????
    http://en.cppreference.com/w/cpp/string/basic_string/size

    string.size() zählt aber nicht die Länge bis zum nächsten '\0' .


Log in to reply