utf8 ostringstream



  • Hallo
    Ich bin benötige eine ostringstream Klasse, die intern utf8 verwendet.
    Mein erster Ansatz:

    class Utf8ostringstream : public std::basic_ostringstream<char> {
      Utf8ostringstream& operator<<(const char& c)
      { 
        //add utf8-result to stringstream
        static_cast< std::ostringstream& >( *this ) << convert::ANSItoUTF8( c ); 
        return *this; 
      } 
    
      Utf8ostringstream& operator<<(wchar_t const * const & wc)
      { 
          static_cast< std::ostringstream& >( *this ) << convert::UTF16toUTF8( wc ); 
    
          return *this; 
      }
    
      //ist für wstring und string sowie einzelne character ebenfalls überladen
      //...
    
      using std::basic_ostringstream<char>::operator<<;
    };
    

    Das klappt für strings sehr gut. Nur sobald bspw eine Zahl hizugefügt wird, wird autom die Elternklasse zurückgegeben und anschließend nicht mehr die string-operatoren der speziellen Klasse aufgerufen. Bei eigenen Klassen kann man sowas durch das "curiously recurring template pattern" lösen. Aber bei std::basic_ostringstream leider nicht. Und ich möchte ja auch nicht alle operatoren in der abgeleiteten Klasse überschreibem. Ketztlich soll er eben nach jeder Operation eine Referenz auf Utf8ostringstream zurückgeben.

    Hat jemand eine andere Idee? Macht es Sinn die hier eine spezielle utf8-Trait-Klasse zu implementieren?

    Hier noch mal das konkrete Problem der bisherigen Lösung:

    Utf8StringStream s;
    s << "ööööö" << 5 << "öööö"; //--> die ersten öööö=utf8, die zweiten=ansi
    


  • ok, hab die Klasse Klasse nun der Einfachheit um eine template Funktion erweitert:

    template< typename T >
       Utf8ostringstream& operator<<( const T& s)
       {
    	   static_cast< std::ostringstream& >( *this ) << s;
    
    	   return *this;
       }
    

    und das using entfernt... Soweit sieht es gut aus. oder steckt der Teufel im Datail?



  • Welches Interesse hat man eigentlich daran intern UTF8 zu verwenden? Zum Speichern aufgrund der Kompaktheit ist es sicherlich geeignet, aber macht es nicht mehr Sinn intern einen Kodierung mit fester Breite zu nehmen (also wchar_t z.B.) und dann zur Ein- und Ausgabe entsprechend mittels der codecvt Facette zu konvertieren?



  • @Melderich: Vielleicht den Speicherplatz?

    In meinem momentanen Projekt verwende ich std::basic_string<char32_t>, habe dafür die ostream/istream-Operatoren (<< und >>) überladen und noch ein paar Konvertierungsfunktionen geschrieben. UTF ist aber sowieso ein heikles Thema, eine UTF-Library oder eine UTF-Klassen enthaltende Library wie wxWidgets oder Qt würde hier sicherlich helfen, wenn auch vielleicht nicht so elegant. Übrigens gibt's hier auch einen Artikel zu UTF und einen Verweis auf eine UTF-Library für C++.



  • Vielleicht den Speicherplatz?

    Wann ist der denn noch ein Problem? "Normale" Texte sind ja keine 5GB groß. Und wenn man irgendwelche Messdaten in Textform verarbeiten muss, dann werden die wohl nur ASCII benutzen, sodass char vollkommen ausreicht.

    Wie gesagt: Um Text auf der Festplatte zu speichern oder im Netzwerk zu übertragen ist UTF8 gut, aber damit innerhalb des Programms zu arbeiten ist doch vergleichsweise umständlich. Wieso also die Mühe? Um ein paar MB Arbeitsspeicher zu sparen (und dafür wahrscheinlich eine schlechtere Performance bei Standardoperationen, wie z.B. das Zugreifen auf den n-ten Buchstaben)?



  • Bei CP gibts eine UTF-8 Facet:
    http://www.codeproject.com/KB/stl/utf8facet.aspx

    Auch bei Boost gibts eine...

    Simon

    Edit:
    Guck diese Threads zum Thema:
    http://www.c-plusplus.net/forum/284605
    http://www.c-plusplus.net/forum/p2034858



  • @theta: danke, die Links helfen mir erst mal weiter!


Anmelden zum Antworten