Sonderzeichen in Strings



  • @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.



  • Zum Öffnen von Dateien solltest du auf Windows grundsätzlich Wide-Character Strings oder std::filesystem::path verwenden. Dann stellt sich die Frage der Codepage nicht. Bzw. nur dort wo zwischen 8-Bit und "wide" konvertiert werden muss. Was man z.B. nicht muss wenn man die Pfade per Command-Line Argument übergeben bekommt oder wenn die Pfade hard-coded sind.



  • @hustbaer sagte in Sonderzeichen in Strings:

    Zum Öffnen von Dateien solltest du auf Windows grundsätzlich Wide-Character Strings oder std::filesystem::path verwenden. Dann stellt sich die Frage der Codepage nicht. Bzw. nur dort wo zwischen 8-Bit und "wide" konvertiert werden muss. Was man z.B. nicht muss wenn man die Pfade per Command-Line Argument übergeben bekommt oder wenn die Pfade hard-coded sind.

    genau an der Stelle hänge ich noch fest std::filesystem::path hate ich noch nicht gesehen aber wie ich es lese funktioniert es mit meinen Momenten Compiler nicht MiniGW,
    Daher bin ich wie auch auf der Seite beschrieben an der wstring als Eingabe ran was mir dabei nur nicht gelingt ist die Konvertierung damit ich es in fstream nutzen kann, da werden keine char_t sondern nur char nutzt.



  • Dafür gibt es dann auch die entsprechenden "wide-string" Klassen: wfstream, wifstream, wofstream, ..



  • @Nokman sagte in Sonderzeichen in Strings:

    wstring als Eingabe ran was mir dabei nur nicht gelingt ist die Konvertierung damit ich es in fstream nutzen kann

    Der fstream Konstruktor der MSVC Standard Library akzeptiert wchar_t* als Pfad. Also falls es darum geht. Wenn das die Standard Library von MinGW nicht kann, dann ist diese unter Windows schlecht brauchbar. Du bist dann auf die 8-Bit CodePage des Systems eingeschränkt.

    Falls es um die Ausgabe in den Stream geht: wenn du dort Wide-Strings brauchst, dann ist das doof. wfstream könntest du dir ansehen, könnte sein dass man damit brauchbar arbeiten kann. Kann ich nix dazu sagen, ausser dass du aufpassen solltest ob dabei dann auch wirklich die garantiert gewünschte CodePage im File landet.

    Was MinGW angeht: kannst du das Tool nicht auf z.B. MSVC portieren? Damit hättest du einen modernen Compiler mit Support für C++17 inklusive std::filesystem.



  • @Th69 sagte in Sonderzeichen in Strings:

    Dafür gibt es dann auch die entsprechenden "wide-string" Klassen: wfstream, wifstream, wofstream, ..

    Dies beziehen sich beim Öffnen auch wieder auf fstream bzw so wie ich es verstehe
    candidate function not viable: no known conversion from 'std::__cxx11::wstring' (aka 'basic_string<wchar_t>') to 'const char *' for 1st argument


Anmelden zum Antworten