Sonderzeichen in Strings



  • Guten Tag,
    ich bin recht neu und viel am rumprobieren nun sitze ich seit Tagen an einen kleiner Problem mit Umlauten. Folgender Code

    #include <iostream>
    using namespace std;
    string name = "Übung String Sonderzeichen üäö !";
    
    int main()
    {
        for (char zeichen : name)
            cout << zeichen;
        cout << endl;
        cout << name << endl;
        return 0;
    }
    
    

    Ausgabe:

    ├£bung String Sonderzeichen ├╝├ñ├ !
    ├£bung String Sonderzeichen ├╝├ñ├ !
    Betõtigen Sie die <RETURN> Taste, um das Fenster zu schlie▀en...
    

    Ich verwende QT Creator zum erstellen. als QString habe ich damit kein Problem aber zur Übung versuche ich es ohne Qt mit der std::string leider komme ich da nicht weiter.

    Ich bin mir auch sehr unsicher ob es am Creator liegt oder wirklich am string klasse.

    Wenn jemand es mir kurz sagen kann woran es liegen könnte würde es mich Freuen. Ich vermute das ich mich Irgendwo total verrenne und es eher ein Fehler bei der Codierung ist.

    Ich nutze QtCreator unter Windows.

    Danke
    Nokman



  • Scheint so, daß Dein Editor UTF-8-Kodierung verwendet. Windows mag aber nicht UTF-8. Die dort übliche Kodierung ist ISO-8551-1 oder so ähnlich (hab jetzt die genaue Nummer nicht im Kopf). Bei der Ausgabe an der Konsole, gibt es aber noch ein Problem. Die Konsole mag wieder eine alte prähistorische Kodierung die verwendet wurde DOS noch das Standardbetriebssystem der Jungs aus Rotmund war. Dafür gibt es dann in der Windows API jetzt eine Fuktion zum Konvertieren. Ich weiß ned auswendig wie die heißt, könnte aber heute Abend bei mir daheim nachschauen.



  • @mgaeckler sagte in Sonderzeichen in Strings:

    Die dort übliche Kodierung ist ISO-8551-1 oder so ähnlich (hab jetzt die genaue Nummer nicht im Kopf).

    Die übliche default Codepage auf Windows ist 1252, die fast aber nicht ganz identisch zu Latin-1 aka. ISO 8859-1 ist.



  • Aber die Windows-Konsole (Eingabeaufforderung) hat standardmäßig 850 (DOS-Latin-1) als Codepage (kann man mittels chcp überprüfen).



  • vielen Dank für die Hinweise,

    Nach umstellen der Codierung auf IBM850 / CP850 / csPC850Multilingual geht es in der Konsole richtig

    jetzt habe ich noch eine kleine andere sache Dabei geht es auch um den String und das Öffnen von dateien.

    #include <iostream>
    #include <fstream>
    using namespace std;
    string dateiName = "../übung/datei.txt";
    string dateiNameue = "../uebung/datei.txt";
    
    int main()
    {
        for (char zeichen : dateiName)
            cout << zeichen;
        cout << endl;
        cout << "std::string " << dateiName << endl;
        fstream *datei = new fstream();
        datei->open(dateiName,ios::in);
        cout << datei->good() << endl;
        datei->close();
        datei->open(dateiNameue,ios::in);
        cout << datei->good() << endl;
        datei->close();
    
        return 0;
    }
    
    ../übung/datei.txt
    std::string ../übung/datei.txt
    0
    1
    Betõtigen Sie die <RETURN> Taste, um das Fenster zu schlie▀en...
    

    ich habe beide Ordner erstellt übung und uebung da wird es aber wo anders dran hängen also müsste ich es umwandeln.



  • @Nokman sagte in Sonderzeichen in Strings:

    fstream *datei = new fstream();

    OT: C++ ist nicht Java. fstream datei;. Dann muss man auch kein close am Ende Aufrufen und es gibt kein Memory Leak.



  • Du gehst davon aus, dass deine Quellcode-Kodierung mit der erwarteten Kodierung der fstream-Open-Funktion übereinstimmt. Das ist nicht der Fall.

    Da dein Quellcode wohl utf-8 kodiert ist, lies bitte: https://utf8everywhere.org/ - insbesondere auch den Abschnitt "How to do text on Windows" inklusive Unterabschnitt "Working with files, filenames and fstreams on Windows".



  • Neben dem schon bisher gesagtem ...

    @Nokman sagte in Sonderzeichen in Strings:

        for (char zeichen : name)
            cout << zeichen;
    

    echt jetzt?



  • @Swordfish Stimmt, der range-based for Loop is viel zu modern. Ich würde eine Iterator-Schleife vorschlagen.



  • @Nokman Das Problem: Windows verwendet beim Speichern von Non-Ascii-dateinamen wide character während Linux und andere Nixen gerne UTF-8 Kodierung verwenden

    Unter Windows must Du daher wide character benutzen unter Nixen Deine Zeichenkette in UTF-8 konvertieren. Wie das st::filesystem objekt das managed, kann ich jetzt leider nicht sagen.



  • Ich Danke viel mals euch Danke für den Link https://utf8everywhere.org/ habe durch umstellen der Quellcode-Kodierung hinbekommen.

    Jetzt werde ich mich damit befassen das ich die Ausgabe in ein anderes Format bringe.

    Ich hatte eins c unter Linux gelernt vor einigen Jahren, durch die Aktuelle zeit habe ich es wieder Aufgenommen und nun versuche ich es unter Windows mit c++, Ich dachte nicht das es damit so ein Problem gibt was ich vorher nie beachtet hatte.

    Danke



  • @hustbaer sagte in Sonderzeichen in Strings:

    @Swordfish Stimmt, der range-based for Loop is viel zu modern. Ich würde eine Iterator-Schleife vorschlagen.

    Ich weiß ja nicht, ich würde operator<<() für strings nehmen!?



  • @Swordfish Ich würde eher den operator ><((((*> nehmen.
    (Hint Hint: mein letzter Beitrag war ironisch gemeint.)



  • @Swordfish Das ist eine ÜBUNG. Da macht man manchmal Sachen, die zu umständlich oder ineffizient sind für produktiven Code, nur um sie mal gesehen zu haben, um sie dann, wenn man sie braucht, wieder aus dem Hinterkopf herzaubern kann. Diesen Vorgang nennt man auch LERNEN.



  • für mich ging es im Grunde nur darum wie die Werte sind, davor hatte ich den Code

    for (char zeichen : dateiName)
            cout << (int)zeichen << endl;
    

    um die Eigentlichen werte zu sehen dies unterschieden sich je nach Codierung bei den Sonderzeichen. Was mir eben bei utf8 aufgefallen war das es so als 2 Zeichen ausgegeben wird und nun wo es richtig ist nur eins.



  • @hustbaer sagte in Sonderzeichen in Strings:

    mein letzter Beitrag war ironisch gemeint.

    ach so, dann ist bloß mein Ironiedetektor defekt gewesen. 👌



  • @Nokman sagte in Sonderzeichen in Strings:

    Was mir eben bei utf8 aufgefallen war das es so als 2 Zeichen ausgegeben wird und nun wo es richtig ist nur eins.

    Naja, utf-8 ist 1, 2, 3 oder 4 Zeichen lang. Mit einem Byte kannst du nicht alle Unicode-Zeichen darstellen, weil es mehr als 256 gibt.

    Wie ist es denn jetzt "richtig"? Hast du die Ratschläge von utf8everywhere befolgt? Oder einen anderen Weg gewählt?



  • @wob sagte in Sonderzeichen in Strings:

    @Nokman sagte in Sonderzeichen in Strings:

    Was mir eben bei utf8 aufgefallen war das es so als 2 Zeichen ausgegeben wird und nun wo es richtig ist nur eins.

    Naja, utf-8 ist 1, 2, 3 oder 4 Zeichen lang. Mit einem Byte kannst du nicht alle Unicode-Zeichen darstellen, weil es mehr als 256 gibt.

    Wie ist es denn jetzt "richtig"? Hast du die Ratschläge von utf8everywhere befolgt? Oder einen anderen Weg gewählt?

    Richtig bedeutet im Moment nur das ich die Zeichencodierung der Datei geändert habe und somit die Umlaute im richtigen Wert sind um Sie an Dateien zu übergeben. Heute am Abend werde ich mir die Zeit nehmen mit Hilfe der Vorschläge beides hinzubekommen. Umlaute werden Dargestellt in der Konsole und die Datei kann geöffnet werden



  • @Nokman Bist du sicher dass die Datei auch in CP 850 ist? CP 850 ist nämlich eher unüblich für den Inhalt von Dateien. Das wird quasi nur für DOS-Zeugs und die {{cmd.exe}} Konsole von Windows verwendet.



  • @hustbaer sagte in Sonderzeichen in Strings:

    CP 850

    Muss ich kurz Richtig stellen
    CP 850, damit geht es nicht die Umlaute zum Öffnen von Datei zu nutzen, dies ist nur für die Console.
    ISO 8551-1 ist zum Öffnen der Datei

    es sind 2 getrennte Programme welche im Moment genau das machen das Eine zeigt Umlaute in der Console das andere kann Umlaute in Dateinamen verarbeiten.

    Nun Probiere ich die beiden zusammenzubringen das es beides in einen geht. Aber da probiere ich ein wenig das es geht weis ich nun.


Log in to reply