VS 2008 wchar_t --> UTF8
-
Hallo,
Das Hauptproblem : ein "Copyright" Zeichen wird nach Konvertierung
wchar_t* --> char*
stets als "A mit Dach" plus "Copyright" angezeigt, sowohl im Debugger
als auch in der ausgebenden Grafik API.Folgende Ansätze sind bereits fehlgeschlagen :
-- Verwenden von WideCharToMultiByte() -- hier wird das gleiche angezeigt.
-- wcstombs_s() scheint kein UTF8 zu erzeugen, der konvertierte String sieht
im Debugger ok aus, ist aber laut verwendeter API kein UTF8 und wird nicht
angezeigt (KEIN Wunder, da UTF8 != MultiByte)-- Wenn ein String im UTF-8 Format direkt in das Programm geschrieben wird,
wird er bereits vom Debugger in obiger falscher weise angezeigt :
z.B. char l_lasttry[] = {'\xc2','\xa9'} ergibt das obige. Dies ergibt
sich auch, wenn man std::string nutzt.-- Ich habe schon das File als unsigned - UTF8 gespeichert.
Das Programm muss ich als "multibyte" kompilieren, da die verwendete
API multibyte nutzt.Hier ein Beispiel, wobei die UTF8Util::ConvertUTF16ToUTF8
bloss WideCharToMultiByte() in korrekter Weise nutzt.wchar_t* buf = L"\u00A9"; CStringA l_cstra = UTF8Util::ConvertUTF16ToUTF8(buf);und hier zur Info die WideCharToMultiByte() Funktion
(von einem Microsoft-Entwickler ...)
Wie gesagt kommt es garnicht unbedingt auf diese Funktion an,
andere Wege führen auch zum gleichen Problem
Ach ja, mit locales hab ichs auch schon versucht ....CStringA ConvertUTF16ToUTF8( __in const WCHAR * pszTextUTF16 ) { // // Special case of NULL or empty input string // if ( (pszTextUTF16 == NULL) || (*pszTextUTF16 == L'\0') ) { // Return empty string return ""; } // // Consider WCHAR's count corresponding to total input string length, // including end-of-string (L'\0') character. // const size_t cchUTF16Max = INT_MAX - 1; size_t cchUTF16; HRESULT hr = ::StringCchLengthW( pszTextUTF16, cchUTF16Max, &cchUTF16 ); if ( FAILED( hr ) ) { AtlThrow( hr ); } // Consider also terminating \0 ++cchUTF16; // // WC_ERR_INVALID_CHARS flag is set to fail if invalid input character // is encountered. // This flag is supported on Windows Vistaand later. // Don't use it on Windows XP and previous. // //#if (WINVER >= 0x0600) // // DWORD dwConversionFlags = WC_ERR_INVALID_CHARS; // //#else DWORD dwConversionFlags = 0; //#endif // // Get size of destination UTF-8 buffer, in CHAR's (= bytes) // int cbUTF8 = ::WideCharToMultiByte( CP_UTF8, // convert to UTF-8 dwConversionFlags, // specify conversion behavior pszTextUTF16, // source UTF-16 string static_cast<int>( cchUTF16 ), // total source string length, in WCHAR's, // including end-of-string \0 NULL, // unused - no conversion required in this step 0, // request buffer size NULL, NULL // unused ); ATLASSERT( cbUTF8 != 0 ); if ( cbUTF8 == 0 ) { AtlThrowLastWin32(); } // Allocate destination buffer for UTF-8 string // CStringA strUTF8; int cchUTF8 = cbUTF8; // sizeof(CHAR) = 1 byte CHAR * pszUTF8 = strUTF8.GetBuffer( cchUTF8 ); // // Do the conversion from UTF-16 to UTF-8 // int result = ::WideCharToMultiByte( CP_UTF8, // convert to UTF-8 dwConversionFlags, // specify conversion behavior pszTextUTF16, // source UTF-16 string static_cast<int>( cchUTF16 ), // total source string length, in WCHAR's, // including end-of-string \0 pszUTF8, // destination buffer cbUTF8, // destination buffer size, in bytes NULL, NULL // unused ); ATLASSERT( result != 0 ); if ( result == 0 ) { AtlThrowLastWin32(); } // Release internal CString buffer strUTF8.ReleaseBuffer(); // Return resulting UTF-8 string return strUTF8; }
-
welche Grafik API?
-
Lordolin schrieb:
-- Wenn ein String im UTF-8 Format direkt in das Programm geschrieben wird,
wird er bereits vom Debugger in obiger falscher weise angezeigt :
z.B. char l_lasttry[] = {'\xc2','\xa9'} ergibt das obige. Dies ergibt
sich auch, wenn man std::string nutzt.Woher soll denn der Debugger auch wissen, dass du der Meinung bist, der Inhalt des char oder std::string sei als UTF-8 zu verstehen. Da musst du schon einen eigenen Visualizer für UTF-8 schreiben.
Hab aus Neugier gerade mal getestet, wie andere es anzeigen. Der C++ Builder 2010 zeigt bei folgendem Code
UnicodeString orig = L"\u00A9"; UTF8String conv = orig;auch an
conv {}
Data
[0] A mit Dach -62 (0xC2)
[1] Copyright Symbol -87 (0xA9)
[2] '\0' 0 (0x00)wenn man die Maus draufhält. Die Debugger interpretieren einfach die einzelnen Zeichen.
Wenn deine Grafik API das auch macht, kann sie halt kein UTF-8.
-
Wenn deine Grafik API das auch macht, kann sie halt kein UTF-8.
Hallo und vielen Dank für die Antwort !
Die API (es handelt sich um VTK von Kitware) kann allerdings UTF-8, zumindest laut Doku ... Schliesslich wird das "Copyright" Zeichen ja auch gerendered, aber mit dem unerwünschten "A mit Dach" davor ...
Dass der Debugger das nun auch so macht ist dann wohl Zufall, und die API erwartet eine andere Art der Konvertierung.Nun habe ich noch folgendes Experiment gemacht : Die API kann auch einen 16- Bit Unicode String, dem habe ich den w_char* im Konstruktor übergeben. Nun gibt es die Funktion vtkUnicodeString.to_utf8(), welche im Grunde einen verkappten std::string zurückgibt, der nun UTF8 sein soll. Allerdings kommt hier das gleiche Problem hoch (beim Rendering, im Debugger eh, aber ist ja wie oben erkannt unabhängig voneinander) !
Also bin ich mit meinem Latein am Ende. Gibt es evtl irgendwelche locale-Settings o.ä., die ich beachten muss ?
Muss die Bibliothek selber evtl mit anderen flags gebaut werden ? (Wobei sie mit UNICODE Flag nicht baut, nur mit MultiChar ...)Beste Grüße,
Lordolin
-
Hmm, habe gerade durch nen QuickHack herausgefunden,
dass alles als Windows ASCII interpretiert wird, obwohl
Beispiele und Doku anderes "suggerieren". NA TOLL. Danke allen für die Hilfe,
das wars dann wohl erstmal mit Unicode. Schade bloss um die Zeit, die ich mit dem
... verbracht hab.LG, Lordolin
-