multibyte zu unicode konvertieren



  • hi,
    gibt es funktionen in c++, mit denen ich multibyte in unicode wandeln kann?



  • Siehe hier zum Beispiel ein Ergebnis von Google:
    http://www.eggheadcafe.com/software/aspnet/33262150/switching-from-multibyte.aspx

    Gruß Kimmi



  • kimmi schrieb:

    Siehe hier zum Beispiel ein Ergebnis von Google:
    http://www.eggheadcafe.com/software/aspnet/33262150/switching-from-multibyte.aspx

    Gruß Kimmi

    Was aber kein Standard-C++ ist (sondern WinAPI, wenn ich das "_T" richtig sehe).

    noobie23 schrieb:

    hi,
    gibt es funktionen in c++, mit denen ich multibyte in unicode wandeln kann?

    Nicht in Standard-C++. Du müsstest also nach einer passenden Bibliothek googlen oder wenn das ausreichen ist im entsprechenden Plattform- oder Framework-spezifischen Forum nachfragen, das zu deiner Umgebung das passendste ist.



  • Kennt ihr gute libs bzw. auch einfache Funktionen, die eine Konvertierung ermöglichen. denn man findet gar nicht viel zu diesem Thema, dass portabel auf mehreren Plattformen läuft.



  • Soweit ich weiß bietet die QString-Klasse von Qt all das.



  • Hi danke für die Antwort.
    Das hatte ich auch schon in betracht gezogen gehabt, nur dann muss ich die Qt library ziehen und meine applikation wird zu groß.
    Das Problem liegt darin, dass mein Webserver eine chinesische datei parsen und weiter leiten soll zum Webbrowser. Da aber die chinesische datei in multibyte codiert geht das nicht. ich muss das ganze umwandeln in utf-8.



  • Du kannst dem Webbrowser doch stumpf sagen was für ein Format der Text hat. Der frisst doch alles.



  • noobie23 schrieb:

    gibt es funktionen in c++, mit denen ich multibyte in unicode wandeln kann?

    Du wirfst Begriffe durcheinander. Unicode an sich ist nur die Definition des Zeichensatzes und beschreibt nicht die kodierung! Multibyte bezeichnet eine Art von Kodierung, aber keine konkrete Kodierung. (Ich nehme mal an, du meinst wchar_t. Aber was da genau hinter steckt hängt vom Compiler und Std-Library ab)

    Kodierungen wären zB UTF-8 oder UTF-32.

    noobie23 schrieb:

    Das Problem liegt darin, dass mein Webserver eine chinesische datei parsen und weiter leiten soll zum Webbrowser. Da aber die chinesische datei in multibyte codiert geht das nicht. ich muss das ganze umwandeln in utf-8.

    http://utfcpp.sourceforge.net/
    http://gcc.gnu.org/onlinedocs/libstdc++/manual/codecvt.html
    http://en.wikipedia.org/wiki/Iconv





  • Hi Leute, danke für die Antworten, aber ich mach das erstmal mit den Windows funktionen.

    Da habe ich aber ein Problem vielleicht kann mir einer von euch helfen:

    string Pfad="C:/chinesische_MultibyteDatei.txt" //eine chinesische Datei
    	string str;
    	string Speicher;
    	ifstream Ifs;
    	Ifs.open(Pfad.c_str(), ios::in);
    	if(Ifs.is_open()!=true)
    		cout<<"Konnte Datei nicht öffnen!\n";
    
    	while(!Ifs.eof())
    	{
    		getline(Ifs,str);
    		Speicher+=str;
    		Speicher+="\n";
    	}
    
    	Ifs.close(); //wird in einem string eingelesen
    
    	int size=Speicher.size()+1;
    	wchar_t*src;
    	int codepage=936;
    
            //hier wird die Windowsfkt. verwendet um widechar daraus zu machen
    	int iRes = MultiByteToWideChar(936, 0, Speicher.c_str(), -1, NULL, 0);  
    	src=new wchar_t[iRes];
    
    	iRes= MultiByteToWideChar(936, 0, Speicher.c_str(), -1, src, iRes); 
    
    	wstring result;
    
    	int i=0;
    	result=src; //hier wird an ein wstring übergeben
    
    	std::wcout<<result; 
    
    	wofstream wOut;
    	wOut.open("neue_chinesische_datei.txt",ios::trunc);
    	wOut.write(src,iRes);
    	wOut.close();
    

    Das Problem ist bei der ausgabe von wstring, wird nur ein sehr kleiner teil ausgegeben. Auch wenn ich dann mit wchar*t direkt in eine Datei schreibe kommt auch nur dieser eine kleine teil in die Datei, dabei hat die Funktion alles umgewandelt. Wisst ihr wo das Problem liegt



  • Du kannst den fogenden Code verwenden. Einfach die beiden Files (StringUtil.h und StringUtil.cpp) erzeugen und den Inhalt reinkopieren.

    Einerseits kannst Du dann die Funktionen make_string(..) make_wstring(..) benutzen. Oder aber die Klassen StringA, StringW und StringT (typedef, abhängig von _UNICODE) direkt benutzen.

    StringUtil.h

    #pragma once
    
    ///////////////////////////////////////////////////////////////////////////////
    
    #include <string>
    #include <vector>
    
    ///////////////////////////////////////////////////////////////////////////////
    
    namespace stringutil
    {
    
    ///////////////////////////////////////////////////////////////////////////////
    
    class StringA
    {
    public:
    	explicit StringA(const char* str);
    	explicit StringA(const wchar_t* str);
    
    	operator const char*() const;
    
    private:
    	std::string _str;
    };
    
    ///////////////////////////////////////////////////////////////////////////////
    
    class StringW
    {
    public:
    	explicit StringW(const char* str);
    	explicit StringW(const wchar_t* str);
    
    	operator const wchar_t*() const;
    
    private:
    	std::wstring _str;
    };
    
    ///////////////////////////////////////////////////////////////////////////////
    
    #ifndef _UNICODE
    typedef StringA StringT;
    #else
    typedef StringW StringT;
    #endif
    
    ///////////////////////////////////////////////////////////////////////////////
    
    typedef std::vector<char> CharBuffer;
    typedef std::vector<wchar_t> WCharBuffer;
    
    #ifndef _UNICODE
    typedef CharBuffer TCharBuffer;
    #else
    typedef WCharBuffer TCharBuffer;
    #endif
    
    ///////////////////////////////////////////////////////////////////////////////
    
    std::string make_string(const wchar_t* str);
    std::string make_string(const std::wstring& str);
    
    std::wstring make_wstring(const char* str);
    std::wstring make_wstring(const std::string& str);
    
    ///////////////////////////////////////////////////////////////////////////////
    
    } // stringutil
    
    ///////////////////////////////////////////////////////////////////////////////
    

    StringUtil.cpp

    #include "stdafx.h"
    #include "StringUtil.h"
    #include <windows.h>
    
    ///////////////////////////////////////////////////////////////////////////////
    
    stringutil::StringA::StringA(const char* str)
    : _str(str)
    {
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    stringutil::StringA::StringA(const wchar_t* str)
    {
    	int len = WideCharToMultiByte(CP_ACP, 0, str, -1, 0, 0, 0, 0);
    	if (0 != len)
    	{
    		CharBuffer buf(len);
    		int err = WideCharToMultiByte(CP_ACP, 0, str, -1, &buf[0], buf.size(), 0, 0);
    		if (0 != err)
    		{
    			_str.assign(buf.begin(), buf.end());
    		}
    	}
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    stringutil::StringA::operator const char*() const
    {
    	return _str.c_str();
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    stringutil::StringW::StringW(const char* str)
    {
    	int len = MultiByteToWideChar(CP_ACP, 0, str, -1, 0, 0);
    	if (0 != len)
    	{
    		WCharBuffer buf(len);
    		int err = MultiByteToWideChar(CP_ACP, 0, str, -1, &buf[0], buf.size());
    		if (0 != err)
    		{
    			_str.assign(buf.begin(), buf.end());
    		}
    	}
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    stringutil::StringW::StringW(const wchar_t* str)
    : _str(str)
    {
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    stringutil::StringW::operator const wchar_t*() const
    {
    	return _str.c_str();
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    std::string stringutil::make_string(const wchar_t* str)
    {
    	return std::string(StringA(str));
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    std::string stringutil::make_string(const std::wstring& str)
    {
    	return std::string(StringA(str.c_str()));
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    std::wstring stringutil::make_wstring(const char* str)
    {
    	return std::wstring(StringW(str));
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    std::wstring stringutil::make_wstring(const std::string& str)
    {
    	return std::wstring(StringW(str.c_str()));
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    


  • Hi, danke für den Code.

    Dieser funktioniert auch, aber es gibt immer noch ein Problem.
    Und zwar wenn ich die chinesischen zeichen ausgeben will bricht das Programm bei mir ab.
    Ich benutze dabei wcout, und der gibt alles aus bis ein Chinesisches zeichen kommt, dann bricht er die Ausgabe abbrupt ab. Wenn ich dass zeichen überspringe gibt er wieder alles aus bis weitere chinesische Zeichen kommen.
    Warum passiert das, kennt ihr das Problem auch?


  • Administrator

    Die Windowskonsole versteht kein Unicode und arbeitet immer noch mit sogenannten Codepages. Es können nur maximal 256 verschiedene Zeichen angezeigt werden. Du musst somit die Codepage deinen Bedürfnissen anpassen:
    http://msdn.microsoft.com/en-us/library/ms686013.aspx

    Oder vergiss es gleich auf der Konsole andere Zeichen als von ASCII auszugeben, im allgemeinen ist es schlicht zu kompliziert dies zu bewerkstelligen. Aber falls du es trotzdem machen möchtest, fragst du am besten mal im WinAPI Forum nach, denn mit dieser Frage bist du im C++ Forum definitiv falsch.

    Grüssli



  • Im obigen Code (StringUtil.h und StringUtil.cpp) kann man die CodePages anpassen. Die Klassen können auch erweitert werden, das die CP konfiguriert werden kann.

    Simon



  • Hi.
    Das Problem ist nicht nur die Konsole, auch wenn ich das ganze in einer Datei schreibe bricht das ganze beim ersten chinesischen zeichen ab.
    Ich habe die ostasiatischen Sprachen bei mir installiert.
    Irgendwie komisch das Problem, ich glaube wchar_t hat vielleicht was damit zu tun, aber ich habe auch keine Ahnung.


  • Administrator

    Kannst du mal "bricht ab" genauer spezifizieren?

    Grüssli



  • Also ich schreibe die Textdatei mit einer Schleife raus.
    ich weiß das 40000 Zeichen von multibyte zu wchar_t konvertiert wurden.
    also lasse ich die schleife bis 40000 laufen. Diese schleife läuft aber nur bis 300, da das 300ste Zeichen ein chinesisches zeichen. Dann bricht die Schleife bei 300 ab.


  • Administrator

    ...

    🙄

    und wie bricht sie ab? Geht dabei die Welt unter? Explodiert dein Computer? Brennt dein Haus nieder? Kommt ein schwarzes Loch vorbei? Wird die Schleife von Aliens entführt? Verschlingt eine Schnecke auf einem dreiköpfigen Fahrrad deine Augen und du siehst das Ende nicht mehr?

    http://www.c-plusplus.net/forum/viewtopic-var-t-is-200753.html
    Vielleicht wäre auch ein in diesem Beitrag erwähntes kurzes Codebeispiel nicht schlecht, welches den Fehler reproduziert.

    Grüssli


Anmelden zum Antworten