Unicode Strings

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Benutzeravatar
Krishty
Establishment
Beiträge: 8250
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Unicode Strings

Beitrag von Krishty »

Alsooooo

Gehen wir davon aus, dass ein Programm das Betriebssystem nutzt um alle Dateien des Startverzeichnisses aufzulisten, deren Name eine bestimmte Buchstabenfolge enthält. Und die ist hard-codet, damit wir das Problem schön mit abdecken.

Normalweise hätten wir jetzt:
(Const Correctness und pass-by-reference ignoriert um das Beispiel zu verkürzen)

    void enumerate(std::wstring dir, std::wstring substr); // Unser Arbeitspferd
    std::wstring getLaunchDir();

und das wird aufgerufen mit böse in den Quelltext geschriebenen Konstanten:

    enumerate(getLaunchDir(), L"foo");

und das ruft unsere tollen gekapselten OS-Funktionen auf, die unter Windows (UTF-16) wären:

    EnumFilesW(wchar_t * dir, wchar_t * substr);
    CreateFileW(wchar_t *);
    OutputStringW(wchar_t *);


und unter Linux (UTF-8):

    enumDir(char * dir, char * substr);
    open(char *);
    print(char *);


Die Implementierungsdetails lassen wir weg; das Ganze kompiliert auf Windows, und … astrein: Wir haben alles mit wchar_t gemacht und müssen nicht konvertieren, weil Windows glücklich ist.

Jetzt kompilieren wir für Linux und … oh scheiße. Linux will ja UTF-8. Was machen wir bloß?! Ja klar! Wir bauen in enumerate(wstring, wstring) Konvertierungen von UCS-32 (denn das ist wstring auf Linux) zu UTF-8 ein! Das überall einzubauen kostet uns drei Entwickler über 8 Tage; das Testen der Konvertierung nochmal zwei Tage, und jetzt klappt es endlich: Jedes Mal, wenn wir enumerate() aufrufen, haben wir eine Shitload Konvertierungen, die kein Schwein braucht (z.B. des Arbeitsverzeichnisses, das wir in UTF-8 vom OS bekommen; für die Rückgabe von getLaunchDir() zu UCS-32 konvertieren; an enumerate() übergeben, und das konvertiert die dann für open() wieder zu UTF-8). Plattformunabhängigkeit ist ein Segen! Und es ist immernoch schneller als Java!
Bild


Währenddessen baut Krishty im dunklen Elfenbeinturm folgendes in seine Header:

    #ifdef WIN32
        typedef wchar_t NativeChar;
    #   define NATIVE(x) L##x
    #else
        typedef char NativeChar;
    #   define NATIVE(x) u8##x
    #endif

    typedef std::basic_string<NativeChar> NativeString;


und ändert die Prototypen zu:

    void enumerate(NativeString dir, NativeString substr);
    NativeString getLaunchDir();


und die fest reingeschriebenen Strings zu:

    enumerate(getLaunchDir(), NATIVE("foo"));

Krishty kompiliert mit Visual C++ für Windows, und die ganzen NativeStrings werden zu UTF-16-wchar_ts. Das String-Literal wird zu einem UTF-16-L"foo". Und der UTF-8-Quelltext, den Visual C++ nicht kann, wird garnicht angesprungen. Visual C++ sieht effektiv den gleichen Quelltext wie vorher.

Jetzt kompiliert Krishty mit GCC für Linux. Die ganzen NativeStrings werden zu UTF-8-chars. Das String-Literal wird zu einem UTF-8-u8"foo". Krishty muss keine Konvertierungsfunktionen schreiben, testen, und nachbessern, weil überhaupt nicht mehr konvertiert werden muss! Und dass wchar_t zu 4 Bytes wird ist egal, weil es garnicht benutzt wird! Heureka! Welch Korn das blinde Huhn dort getroffen hat!

Aber außerhalb des Elfenbeinturms sind nunmal alle der Meinung, Plattformunabhängigkeite bedeutete, dass meine Strings auf jeder Plattform dieselben Binärdaten haben. Und darum sitzt Krishty auch im Elfenbeinturm und spielt nicht mit anderen Entwicklern in der Sonne: Krishty schreibt alles selber weil Drittbibliotheken grundsätzlich denselben scheiß Fehler machen; egal, mit wie vielen Märchen man die Leute aufzuklären versucht.

Und wenn Krishty nicht gestorben ist, „portiert“ die Firma ihre „gekapselten“ „Wrapper“ noch heute.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: Unicode Strings

Beitrag von Niki »

Krishty, mein Kompliment, du hast durchaus eine gewisse Genialität!

Zwar brauche ich jetzt Konvertierungen an anderen Stellen (z.B. bei Sachen wie Font-Rendering mit Wortumbruch), aber ich glaube, dass die Menge der Konvertierungen drastisch sinkt. Damit meine ich jetzt nicht die Anzahl der Konvertierungen pro Frame, sondern die Anzahl der Orte im Quellcode wo Konvertierung nötig wird. Es sei denn Du hast da auch noch eine geniale Idee.

Aber deine Post hat's jetzt voll gebracht! Ich habe mich entschieden und werde deinem Beispiel folgen. Vielen herzlichen dank dafür :)
Benutzeravatar
Biolunar
Establishment
Beiträge: 154
Registriert: 27.06.2005, 17:42
Alter Benutzername: dLoB

Re: Unicode Strings

Beitrag von Biolunar »

Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Unicode Strings

Beitrag von BeRsErKeR »

Grundsätzlich gebe ich dir recht. Besonders wenn man nur die Plattformunabhängigkeit im Auge hat. Ich persönlich bin kein großer Freund von typedefs und Makros. Ich weiß gern mit welchen Daten ich es zu tun habe, wobei das heutzutage wohl an Bedeutung verliert und ruhig schön abstrakt sein kann. In diesem Fall wird das wohl auch keine größeren Probleme bereiten. Vielleicht sollte ich meine Sichtweise bei Strings einfach ändern auf "Ein String besteht aus Zeichen" und nicht mehr auf "Ein String besteht aus <hier Encoding einfügen>-Zeichen".
Ohne Input kein Output.
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: Unicode Strings

Beitrag von Niki »

Ich bin auch kein Fan von Code der mit Makros durchzogen ist. Aber das ist in Krishty's Post ja auch nicht so. Du hast halt irgendwo eine Header-Datei wo das einmal gemacht wird. Ausnahme ist das NATIVE(x) Makro, aber da sehe ich momentan so oder so keine andere Lösung. Überall sonst hast du NativeString ohne Makros. #ifdef DEBUG ist da schlimmer, und selbst das akzeptiere ich noch.
Zuletzt geändert von Niki am 13.04.2013, 18:20, insgesamt 1-mal geändert.
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Unicode Strings

Beitrag von eXile »

Biolunar hat geschrieben:http://www.utf8everywhere.org/
Widerspricht dies nicht genau dem, was Krishty gesagt hat?

UTF-8 Everywhere:
  • Benutze intern UTF-8
  • Konvertiere an allen Anknüpfungspunkten in die jeweilige Zieldarstellung (Windows-API: UTF-16, Linux-API: UTF-8)
  • Braucht mehr Konvertierungen, als man eventuell bei der internen Benutzung von UTF-16 unter Windows, UTF-8 unter Linux bräuchte
Krishty:
  • Benutze intern die Darstellung, die von den Anknüpfungspunkten benötigt wird (Windows: UTF-16, Linux: UTF-8)
  • Konvertiere garnicht
  • Was ist, wenn unterschiedliche APIs unterschiedliche Darstellungen brauchen, wie beispielsweise die WinAPI und Netzwerk-Kommunikation?
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: Unicode Strings

Beitrag von Niki »

eXile hat geschrieben:
Biolunar hat geschrieben:http://www.utf8everywhere.org/
Widerspricht dies nicht genau dem, was Krishty gesagt hat?
Ja und nein. Krishty's Unix-Version ist UTF-8. Und wenn sich die WinAPI da mal ändern würde (bezweifle ich), dann würde der Ansatz auch unter WinAPI zu UTF-8 werden.

Der gegebene Link ist ja ganz gut und schön, und die Absichten hervorragend. Aber das ändert nichts daran das Windows nun mal so ist wie Windows ist. Und Tatsache ist, das Kristhy's Ansatz da echt Nerven spart, und das ist mir wichtig.
Benutzeravatar
Krishty
Establishment
Beiträge: 8250
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Unicode Strings

Beitrag von Krishty »

Ihr könnt das Makro ein wenig verschönern:

    #define N L\

bzw.

    #define N u8\

Damit sieht das dann wie bloß ein weiterer Literal-Typ aus:

    N"foo"

Ich würde es aber nicht empfehlen weil vielleicht irgendwann mal ein Funktionsaufruf oder eine Konvertierung nötig sein könnte, und nachträglich kriegt ihr keine Klammern mehr um den String.


Nachtrag: Funktioniert mit keinem standardkonformen Compiler; vergesst das!

————

Was die anderen APIs und Drittbibliotheken angeht: Man muss natürlich konvertieren; klar. Wenn man zwei Untersysteme hat, die mit unterschiedlichen Kodierungen arbeiten, kann auch ich die Konvertierungen nicht einfach wegzaubern.

Aber wenn das Font Rendering z.B. in UTF-16 arbeitet und das Datenbanksystem auch, und das Font-Rendering ständig durch die Datenbank gefüttert wird, würde ich eben einen zweiten String-Typen nur für diese Interaktion einführen und NativeString nur für betriebssystemspezfische Sachen benutzen. Ich gehe auch kaum davon aus, dass der Font Renderer jeden Frame tausend frisch empfangene Dateipfade ins Spiel rendert.

————

Noch was zu Dateien: Wenn ihr die Strings binär wegschreibt, sind die Dateien natürlich nicht unter den Plattformen austauschbar. Das wären sie aber sowieso nicht, weil sich ja z.B. Endianness und Ausrichtung von Plattform zu Plattform unterscheiden.
Zuletzt geändert von Krishty am 22.05.2013, 17:09, insgesamt 1-mal geändert.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: Unicode Strings

Beitrag von Niki »

Krishty hat geschrieben:Ich würde es aber nicht empfehlen weil vielleicht irgendwann mal ein Funktionsaufruf oder eine Konvertierung nötig sein könnte, und nachträglich kriegt ihr keine Klammern mehr um den String.
Ich ziehe ein NATIVE(x) Makro sowieso vor, wenn auch vielleicht umbenannt. Einfach nur ein N würde ich nicht wagen. Dazu gibt es mir in den Plattform SDKs zu viele willkürlich gewählte Makros die sich mit Namen überschneiden die man gerne nutzen würde. Es geht mir schon auf den Senkel wenn so was wie WindowManager::CreateWindow erstmal mit dem Win32 Makro ins Gehege kommt. Oder wenn VisualAssist mir HandleManager::GetObject() erstmal in HandleManager::GetObjectW() umwandelt. So was wie NATIVE kann man dann noch recht einfach umbenennen, was ich von N nicht behaupten kann.
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: Unicode Strings

Beitrag von Niki »

Krishty hat geschrieben:Noch was zu Dateien: Wenn ihr die Strings binär wegschreibt, sind die Dateien natürlich nicht unter den Plattformen austauschbar. Das wären sie aber sowieso nicht, weil sich ja z.B. Endianness und Ausrichtung von Plattform zu Plattform unterscheiden.
Das sind für mich Dateiformate, und die behandle ich immer separat, mit entsprechenden Konvertierungen. Das trifft ja auch nicht nur auf Strings zu, sondern auch auf alle anderen Typen die mehr als 1 Byte benutzen.
Benutzeravatar
Biolunar
Establishment
Beiträge: 154
Registriert: 27.06.2005, 17:42
Alter Benutzername: dLoB

Re: Unicode Strings

Beitrag von Biolunar »

Niki hat geschrieben:Ich will das Projekt aber irgendwann mal auf andere Plattformen porten.
Dann benutz nicht diese Missgeburt, die sich UTF-16 schimpft. Bitte. UTF-16 führt zu Wut, Wut führt zu Hass, Hass führt zu unsäglichem Leid. Begib dich nicht auf dieses Pfad!
Benutzeravatar
Biolunar
Establishment
Beiträge: 154
Registriert: 27.06.2005, 17:42
Alter Benutzername: dLoB

Re: Unicode Strings

Beitrag von Biolunar »

Krishty hat geschrieben:Noch was zu Dateien: Wenn ihr die Strings binär wegschreibt, sind die Dateien natürlich nicht unter den Plattformen austauschbar. Das wären sie aber sowieso nicht, weil sich ja z.B. Endianness und Ausrichtung von Plattform zu Plattform unterscheiden.
UTF-8 hat keine Endianess Probleme.
Benutzeravatar
Biolunar
Establishment
Beiträge: 154
Registriert: 27.06.2005, 17:42
Alter Benutzername: dLoB

Re: Unicode Strings

Beitrag von Biolunar »

eXile hat geschrieben:
Biolunar hat geschrieben:http://www.utf8everywhere.org/
Widerspricht dies nicht genau dem, was Krishty gesagt hat?
Yupp, tut es. Wenn man nur unter Windows bleibt und keine Texte in Dateien schreibt und keine Texte übers Netzwerk versendet, kann ich es verstehen warum man der Bequemlichkeit halber UTF-16 verwendet. Falls man diese Dinge doch tut, sollte man sowieso konvertieren. Warum dann nicht gleich direkt nach dem man die Strings von der API erhalten hat?
Benutzeravatar
Krishty
Establishment
Beiträge: 8250
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Unicode Strings

Beitrag von Krishty »

Weil man nicht jeden String, den man jemals irgendwo von irgendeiner API kriegt, in eine Datei schreibt.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: Unicode Strings

Beitrag von Niki »

Letztendlich werde ich den NativeString fürs Durchreichen benutzen. Dann werde ich einen zweiten String-Typen für lokale String-Verarbeitung haben, in dem ich einfach auf Code-Points zugreifen kann (möglicherweise UCS-32). Zu dem wird es einen Converter geben, der zwischen beiden Formaten umwandeln kann. Eins ist jedenfalls klar... ich schreibe keinen UTF-8 Lexer!
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: Unicode Strings

Beitrag von Artificial Mind »

Niki hat geschrieben:Eins ist jedenfalls klar... ich schreibe keinen UTF-8 Lexer!
UTF8 <-> UTF32

Code: Alles auswählen

enum class UTF8State
{
    Initial,

    Range2,

    Range3,
    Range3_1,

    Range4,
    Range4_1,
    Range4_2
};

string utf8encode(const vector<int> &v)
{
    ostringstream str;
    for (int c: v)
    {
        if ( c == -1 ) continue;
        if ( c < (1 << (7)) ) str << (char)c;
        else if ( c < (1 << (6+5)) )
        {
            str << (char)(192 + (31 & (c >> 6)));
            str << (char)(128 + (63 & (c >> 0)));
        }
        else if ( c < (1 << (6+6+4)) )
        {
            str << (char)(224 + (15 & (c >> 12)));
            str << (char)(128 + (63 & (c >> 6)));
            str << (char)(128 + (63 & (c >> 0)));
        }
        else if ( c < (1 << (6+6+6+3)) )
        {
            str << (char)(240 + (7 & (c >> 18)));
            str << (char)(128 + (63 & (c >> 12)));
            str << (char)(128 + (63 & (c >> 6)));
            str << (char)(128 + (63 & (c >> 0)));
        }
        else throw logic_error("Error encoding");
    }
    return str.str();
}
vector<int> utf8decode(const string &data)
{
    UTF8State utf8 = UTF8State::Initial;
    vector<int> v;
    for (char c : data)
    {
        static int utf8Char = 0;

        // UTF-8 decode
        switch(utf8)
        {
        case UTF8State::Initial:
            if ( (c & 128) == 0 ) v.push_back(c);
            else if ( ( c & 224 ) == 192 ) { utf8Char = (c & 31) << 6; utf8 = UTF8State::Range2; }
            else if ( ( c & 240 ) == 224 ) { utf8Char = (c & 15) << 12; utf8 = UTF8State::Range3; }
            else if ( ( c & 248 ) == 240 ) { utf8Char = (c & 7) << 18; utf8 = UTF8State::Range4; }
            else throw logic_error("UTF8 Decoding failed in state Initial");
            break;

        case UTF8State::Range2:
            if ( (c & 192 ) != 128 ) throw logic_error("UTF8 Decoding failed in state Range2");
            utf8Char += ( c & 63 );
            utf8 = UTF8State::Initial;
            v.push_back(utf8Char);
            break;

        case UTF8State::Range3:
            if ( (c & 192 ) != 128 ) throw logic_error("UTF8 Decoding failed in state Range3");
            utf8Char += ( c & 63 ) << (6);
            utf8 = UTF8State::Range3_1;
            break;
        case UTF8State::Range3_1:
            if ( (c & 192 ) != 128 ) throw logic_error("UTF8 Decoding failed in state Range3_1");
            utf8Char += ( c & 63 );
            utf8 = UTF8State::Initial;
            v.push_back(utf8Char);
            break;

        case UTF8State::Range4:
            if ( (c & 192 ) != 128 ) throw logic_error("UTF8 Decoding failed in state Range4");
            utf8Char += ( c & 63 ) << (6+6) ;
            utf8 = UTF8State::Range4_1;
            break;
        case UTF8State::Range4_1:
            if ( (c & 192 ) != 128 ) throw logic_error("UTF8 Decoding failed in state Range4_1");
            utf8Char += ( c & 63 ) << ( 6);
            utf8 = UTF8State::Range4_2;
            break;
        case UTF8State::Range4_2:
            if ( (c & 192 ) != 128 ) throw logic_error("UTF8 Decoding failed in state Range4_2");
            utf8Char += ( c & 63 );
            utf8 = UTF8State::Initial;
            v.push_back(utf8Char);
            break;
        }
    }
    return v;
}
UTF16 <-> UTF32

Code: Alles auswählen


vector<char16_t> utf16encode(const vector<int> &v)
{
    vector<char16_t> str;
    for (int c : v)
    {
        if ( c < 0x10000 )
            str.push_back(c);
        else
        {
            int u = c - 0x10000;
            str.push_back((54 << 10) + ((u & (1023 << 10)) >> 10));
            str.push_back((55 << 10) + ((u & (1023 <<  0)) >>  0));
        }
    }
    return str;
}
vector<int> utf16decode(const vector<char16_t> &v)
{
    vector<int> str;
    for (unsigned int i = 0; i < v.size(); ++i)
    {
        char16_t c = v[i];

        if ( c < 0xD800 || c > 0xDFFF )
            str.push_back(c);
        else
        {
            if ( c < 0xD800 || c > 0xDBFF ) throw logic_error("Invalid UTF16");
            if ( i+1 >= v.size() ) throw logic_error("Invalid UTF16 (eos)");

            ++i;
            char16_t c2 = v[i];

            int u = ((c & 1023) << 10) + (c2 & 1023);
            str.push_back(u + 0x10000);
        }
    }
    return str;
}
You're welcome ;)

(Ja, man kriegt es auch in <100 Zeilen hin, aber das hier funktioniert, das reicht mir ;) )
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Unicode Strings

Beitrag von BeRsErKeR »

Also ich würde lieber bei den kleinen Datenmengen, die ich von der OS-API erhalte oder die ich hinschicke konvertieren, als beim Lesen und Schreiben von beliebig großen Dateiinhalten. Es ist schon ein großer Unterschied wenn ich 200 Zeichen eines Pfades von UTF-16 auf UTF-8 konvertieren muss, als mehrere KB an Text, den ich in eine Datei schreiben will. Da heutzutage die Mehrheit aller textbasierten Dateien mit UTF-8 arbeiten wäre das schon von Vorteil direkt mit UTF-8 Strings zu arbeiten.
Ohne Input kein Output.
Benutzeravatar
Krishty
Establishment
Beiträge: 8250
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Unicode Strings

Beitrag von Krishty »

Kannst du mir erklären, was die Größe meiner Textdateien damit zu tun hat, ob ich irgendwo einen Dateipfad in eine andere Kodierung konvertiere?!

Hier vollkommen belanglose Generalisierungen mit aus der Luft gegriffenen Extrembeispielen zu verschwurbeln bringt doch keinem was. Niki arbeitet hier nicht an einem portablen Notepad 2015 mit Leerlauf-Datei-öffnen-Schleife. Wann man welche Datei wie kodiert ist ein hochspezielles Problem und hat nichts damit zu tun, ob ich CreateFile() nun für UTF-8 oder UTF-16 kapsle.

Ich finde es auch immer lustig, wie ich hier als realitätsfremd und radikal hingestellt werde wenn ich keine STL benutzen will, aber Leute davon überzeugt sind, dass man die komplette WinAPI nach UTF-8 „kapseln“ muss damit man irgendwann mal irgendeinen nicht näher genannten Dateiinhalt schneller schreiben kann.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Schrompf
Moderator
Beiträge: 4859
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Unicode Strings

Beitrag von Schrompf »

Krishty hat geschrieben:Ich finde es auch immer lustig, wie ich hier als realitätsfremd und radikal hingestellt werde
Tut ja niemand. Hier haben nur andere Leute ihre abweichende Meinung verkündet und begründet. Also bleib mal entspannt.

Ich persönlich halte es wie Biolunar: utf8 überall. Auch auf Windows. Die Konvertierungen zwischen den ganzen Kodierungstabellen macht bei mir boost::locale. Einige Stellen benötigen damit in der Tat Konvertierungen, aber das ist halt so. Dafür habe ich Gewissheit, was ich bekomme, wenn ich Dateinamen aus Dateien lese. Und schlagt mich, aber bei mir ist das normal.

Vielleicht erschlägt es mich ja irgendwann, wenn ich mal ne Linux-Konvertierung angehe. Aber dann habe ich wegen Direct3D -> OpenGL eh ganz andere Probleme. Und da das ganze Framework vor langer langer Zeit auch schonmal Multiplattform auf PowerPC und x86 lief, glaube ich, dass ich vorbereitet bin.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: Unicode Strings

Beitrag von Niki »

@Artificial Mind: Super! Danke für den Code. Ich hatte gehofft neuen zu finden :) Meiner basiert noch auch dem alten UTFCONV Source von Unicode, der wegen Schwachstellen zurückgezogen wurde. Stattdessen ist da jetzt diese Monstrosität von Bibliothek deren Namen ich vergessen habe. Gut für ein Betriebssystem, aber für mich ein bisserl zu bombastisch.

Eins verstehe ich allerdings nicht... wieso hast du das als Antwort auf "Eins ist jedenfalls klar... ich schreibe keinen UTF-8 Lexer!" genutzt? :o
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: Unicode Strings

Beitrag von Niki »

Schrompf hat geschrieben:Dafür habe ich Gewissheit, was ich bekomme, wenn ich Dateinamen aus Dateien lese. Und schlagt mich, aber bei mir ist das normal.
Redest du von Dateinamen in normalen Textdateien, oder von Dateinamen in Binärdateien eigenen Formates? Bei normalen Textdateien kann man sich heutzutage über das Format ja nicht wirklich gewiss sein. Mit BOM, ohne BOM, LE, BE, oder noch was anderes.

Und wieso sollte man dich schlagen wenn du Dateinamen in eine Datei schreibst? :D Für meine Ressourcen-Archivdateien werde ich das auch tun.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Unicode Strings

Beitrag von BeRsErKeR »

Krishty hat geschrieben:Kannst du mir erklären, was die Größe meiner Textdateien damit zu tun hat, ob ich irgendwo einen Dateipfad in eine andere Kodierung konvertiere?!

Hier vollkommen belanglose Generalisierungen mit aus der Luft gegriffenen Extrembeispielen zu verschwurbeln bringt doch keinem was. Niki arbeitet hier nicht an einem portablen Notepad 2015 mit Leerlauf-Datei-öffnen-Schleife. Wann man welche Datei wie kodiert ist ein hochspezielles Problem und hat nichts damit zu tun, ob ich CreateFile() nun für UTF-8 oder UTF-16 kapsle.
Nimm es nicht persönlich. Die Diskussion lief weiter und andere haben sich eingeklinkt. Daher bin ich auch darauf eingegangen und nicht nur auf das ursprüngliche Problem.

Wenn ich den Weg nehme, den du vorgeschlagen hast, habe ich (sofern ich kein separates String-Format für die Ein-/Ausgabe für Textdateien bzw. für Stringverarbeitung nutze) im gesamten Programm ein bestimmtes Encoding für meine Strings (Windows: UTF-16, Linux: UTF-8, usw). Wenn ich jetzt (unabhängig von der Problemstellung dieses Threads - daher nicht persönlich nehmen, ich habe nur weiter rumgedacht) zusätzlich viel mit Textdateien hantiere (die sehr häufig UTF-8 verwenden) habe ich auf Windows den Nachteil, dass ich nicht direkt die Strings in Dateien schreiben kann oder von ihnen auslesen kann. Dafür ist dann eine Konvertierung nötig. Hätte ich aber plattformunabhängig UTF-8-Strings, hätte ich auch auf keiner Plattform diesen Nachteil und müsste nur an der Schnittstelle zur Plattform-API konvertieren (dort aber in der Regel nur sehr kleine Strings).

Natürlich ist das nur ein Beispiel und man könnte jetzt auch entgegenstellen, dass man ja auch mit UTF-16-Dateien zu tun haben könnte oder für Nicht-UTF-8-Dateien eh konvertieren muss. Ich wollte damit auch nicht sagen, dass dein (Krishty) Ansatz Blödsinn ist - es waren nur Gedanken, wo die andere Variante eventuell Vorteile haben könnte. Vorallem auch für mich nicht so unwichtig, da ich in meinen Tools sehr häufig mit großen Textdaten zu tun habe, die zu 90% UTF-8 sind.

Krishty hat geschrieben:Ich finde es auch immer lustig, wie ich hier als realitätsfremd und radikal hingestellt werde wenn ich keine STL benutzen will, aber Leute davon überzeugt sind, dass man die komplette WinAPI nach UTF-8 „kapseln“ muss damit man irgendwann mal irgendeinen nicht näher genannten Dateiinhalt schneller schreiben kann.
Ich finde deine Art eigentlich sehr sympatisch und lehrreich. Realitätsfremd und radikal muss auch nichts schlechtes sein - wobei ich nicht denke, dass das auf dich zutrifft. Ich denke eher dass du einfach an Probleme anders rangehst als viele andere. Aber sowas finde ich wichtig. Ich hab schon oft bei einem Beitrag von dir gedacht "Hmm so hab ich das noch gar nicht betrachtet. Gute Idee". Also lass dich nicht unterkriegen! ;)
Ohne Input kein Output.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4859
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Unicode Strings

Beitrag von Schrompf »

Auf die Gefahr, für religiös gehalten zu werden: boost::filesystem macht das eigentlich wie Krishty - es bevorzugt native Kodierung. Allerdings bietet es auch Konvertierungen an.

Ich rede beim Lesen von Dateinamen aus Dateien nur von Textdateien. Bei Textdateien musst Du selbst definieren, welches Encoding Du haben willst, oder mit allen umgehen können. Und das heißt wohl bei Windows entweder UTF16 oder Windows-1251, bei Linux... keine Ahnung. UTF8 vielleicht?

Binärdateien, die ich lesen will, habe ich entweder selbst geschrieben und damit habe ich die volle Kontrolle und die verdammte Pflicht, mir vorher eine Kodierung zu überlegen. Und meine Entscheidung habe ich ja schon geschrieben: UTF8. Oder ich habe Binärdateien von anderen Leuten, und die folgen ja hoffentlich einer öffentlich einsehbaren Spezifikation. Sonst habe ich ganz andere Probleme als die exakte Bytefolge des Zeichens 'é' :-)
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Unicode Strings

Beitrag von BeRsErKeR »

Schrompf hat geschrieben:Binärdateien, die ich lesen will, habe ich entweder selbst geschrieben und damit habe ich die volle Kontrolle und die verdammte Pflicht, mir vorher eine Kodierung zu überlegen.
Dazu fallen mir gerade die UTF-16-kodierten GUIDs im CHM-Format (welches wohlbekannt von Microsoft stammt) ein, wo dann nur halb soviele Bytes vorhanden waren. Sprich die Hälfte der GUID fehlt in jeder Datei, aber man hat schöne 0-Bytes dazwischen. :lol: Da waren wieder Experten am Werk. Vorallem weil Unicode bei GUIDs sehr wichtig ist (Vorsicht, dieser Beitrag enthält Sarkasmus). Also sei dir auch bei Binärdateien nicht so sicher Schrompf. :D
Zuletzt geändert von BeRsErKeR am 13.04.2013, 21:20, insgesamt 2-mal geändert.
Ohne Input kein Output.
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: Unicode Strings

Beitrag von Niki »

Schrompf hat geschrieben:Auf die Gefahr, für religiös gehalten zu werden: boost::filesystem macht das eigentlich wie Krishty - es bevorzugt native Kodierung. Allerdings bietet es auch Konvertierungen an.
Auch wenn ich das jetzt von Schrompf zitiere, so ist die Antwort nicht direkt für Schrompf sondern für alle. Das Zitat deutet nämlich auf etwas hin was hier anscheinend ein wenig übersehen wird, und das ist die Tatsache, dass Krishty's Lösung die oben beschriebene Art der Konvertierung keineswegs ausschließt.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: Unicode Strings

Beitrag von Artificial Mind »

Niki hat geschrieben:Eins verstehe ich allerdings nicht... wieso hast du das als Antwort auf "Eins ist jedenfalls klar... ich schreibe keinen UTF-8 Lexer!" genutzt? :o
Ach ich wollte nur ausdrücken dass UTF-8 und UTF-16 gar nicht so schlimm sind wenn man sich kurz einliest. Du klangst so als wenn "UTF-8 Lexer schreiben" out-of-question ist und eine total absurde Idee wäre ;) (Vielleicht hast du auch was anderes gemeint und ich habe dich nur missverstanden)
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: Unicode Strings

Beitrag von Niki »

Artificial Mind hat geschrieben:
Niki hat geschrieben:Eins verstehe ich allerdings nicht... wieso hast du das als Antwort auf "Eins ist jedenfalls klar... ich schreibe keinen UTF-8 Lexer!" genutzt? :o
Ach ich wollte nur ausdrücken dass UTF-8 und UTF-16 gar nicht so schlimm sind wenn man sich kurz einliest. Du klangst so als wenn "UTF-8 Lexer schreiben" out-of-question ist und eine total absurde Idee wäre ;) (Vielleicht hast du auch was anderes gemeint und ich habe dich nur missverstanden)
Nur um sicher zu gehen, dass wir vom selben reden: Lexer = Lexical Analyzer, die Vorstufe eines Parsers. Für viele in Form von Lex und Flex bekannt.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: Unicode Strings

Beitrag von Artificial Mind »

Niki hat geschrieben:
Artificial Mind hat geschrieben:
Niki hat geschrieben:Eins verstehe ich allerdings nicht... wieso hast du das als Antwort auf "Eins ist jedenfalls klar... ich schreibe keinen UTF-8 Lexer!" genutzt? :o
Ach ich wollte nur ausdrücken dass UTF-8 und UTF-16 gar nicht so schlimm sind wenn man sich kurz einliest. Du klangst so als wenn "UTF-8 Lexer schreiben" out-of-question ist und eine total absurde Idee wäre ;) (Vielleicht hast du auch was anderes gemeint und ich habe dich nur missverstanden)
Nur um sicher zu gehen, dass wir vom selben reden: Lexer = Lexical Analyzer, die Vorstufe eines Parsers. Für viele in Form von Lex und Flex bekannt.
Ok dann möchte ich auch sicher gehen: Was unterscheidet einen UTF8-Lexer von einem normalen Lexer?
Benutzeravatar
Krishty
Establishment
Beiträge: 8250
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Unicode Strings

Beitrag von Krishty »

Die Berücksichtigung von Right-to-Left Marks und unterschiedlichen Kodierungen für denselben Buchstaben?
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: Unicode Strings

Beitrag von Artificial Mind »

Reden wir von UTF-8 als Enkodierung oder von Unicode als Zeichensatz?
Antworten