Frage zu wchar_t in Visual Studio 2008
-
Hallo, ich benutze den Visual C++ 2008 Express Edition compiler. Leider funktioniert hier folgender Code nicht so, wie ich das will:
#include <iostream> #include <string> #include <fstream> using namespace std; int main() { wstring text(L" "); //stellt Euch hier ein paar kyrillische Buchstaben vor //kann das Forum offensichtlich nicht anzeigen :) wcout<<text; //Konsole bleibt leer wofstream schreiben(L"wtest.txt"); schreiben<<text; //das textdokument wird zwar erstellt, bleibt aber leer schreiben.close(); }Ich habe schon im Release Modus unter Projekt -> konsolenanwendung-Eigenschaften -> Allgemein -> Zeichensatz auf Unicode und Multi-Byte Zeichensatz gestellt, allerdings ohne Erfolg. Was mache ich also falsch

-
Kann dein Editor, mit dem du dir die Ausgabe anschaust, die Zeichen überhaupt anzeigen? Überprüf das doch mal...
-
Naja, das Textdokument ist 0 Byte groß. Zum Anschauen benutze ich einfach den Texteditor von Windows...
Aber ich habe gerade folgendes gesehen:cout<<text.size(); //Gibt 5 aus, das stimmt auch wcout<<text.size(); //Gibt nichts ausAnscheinend kann meine Konsole nicht mit wcout umgehen Oo Kann das sein?
-
Hm, ich habe jetzt mal ein bisschen gegooglelt, aber keiner der Tipps konnte helfen.
wstring text(L"\u0430\u043A\u043C\u0430\u043B"); //escapesequenzen statt den richtigen Buchstaben wcout<<text; //noch immer kein Output in die Konsole cout<<text.size(); //gibt 5 aus (was stimmt) wcout<<text.size(); //immernoch kein Output wofstream schreiben(L"wtest", ios::binary); //binär in Datei schreiben schreiben<<text; //wieder wird eine leere, 0 byte große //Datei namens "wtest" erstellt schreiben.close();Und das sowohl bei "unicode" als auch "multi-byte" projekt Settings.
-
Ev. hilfts weiter:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-244120-and-highlight-is-konsole+kyrillisch.html
-
Ich hoffe du hast schon geprüft, ob der Code mit lateinischen Buchstaben so funktioniert wie er soll?
-
It0101 schrieb:
Ich hoffe du hast schon geprüft, ob der Code mit lateinischen Buchstaben so funktioniert wie er soll?
Ja klar. Ich teste gerade mit folgendem Programm:
#include <iostream> #include <fstream> #include <string> using namespace std; int main() { wstring wtext(L"\u0430\u043A\u043C\u0430\u043B"); //auch schon probiert: statt der escape sequenzen die kyrillischen Buchstaben string text("test"); wofstream wschreiben("wtest"); //auch schon probiert: wofstream wschreiben(L"wtest"); ofstream schreiben("test"); schreiben<<text; // in "test" steht "test" drinne. Stimmt! wschreiben<<wtext; // "wtest" bleibt leer return 0; }Herausgefunden habe ich, dass die Windows Konsole nur ASCII anzeigen kann. Also beschränke ich mich jetzt auf das schreiben/lesen von Dateien.
theta schrieb:
Ev. hilfts weiter:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-244120-and-highlight-is-konsole+kyrillisch.htmlIn einem Link in dem artikel habe ich jetzt folgenden Codeschnipsel gefunden:
//include <locale> wofstream my_of("myfile.txt"); locale loc(locale::classic(), new codecvt_utf8<wchar_t>); // Locale: von Classic (US-ASCII) nach UTF-8 my_of.imbue(loc); my_of << L"Hello" << endl;Allerdings kompiliert es bei mir nicht:
1>.\main.cpp(35) : error C2061: Syntaxfehler: Bezeichner 'codecvt_utf8' 1>.\main.cpp(35) : error C2664: 'std::locale::locale(const char *,std::locale::category)': Konvertierung des Parameters 1 von 'const std::locale' in 'const char *' nicht möglich 1> Kein benutzerdefinierter Konvertierungsoperator verfügbar, der diese Konvertierung durchführen kann, oder der Operator kann nicht aufgerufen werdenWas mache ich hier falsch? ich will doch nur kyrillische Buchstaben in der Datei stehen haben

-
Versuchs mal so:
// Das müsste eigentlich funktionieren, ist aber jetzt nur mit UTF16 Little Endian getestet // Siehe auch http://de.wikipedia.org/wiki/Byte_Order_Mark template<typename ValueType> std::vector<char> getByteOrderMark() { assert( CHAR_BIT == 8 ); assert( sizeof(unsigned short) == 2 ); assert( sizeof(unsigned int) == 4 ); const unsigned char utf8[] = { 0xEF, 0xBB, 0xBF }; const char* utf8ptr = reinterpret_cast<const char*>( utf8 ); if ( sizeof(ValueType) == 1 ) return std::vector<char>( utf8ptr, utf8ptr+sizeof(utf8) ); const unsigned short utf16 = 0xFEFF; const char* utf16ptr = reinterpret_cast<const char*>( &utf16 ); if ( sizeof(ValueType) == 2 ) return std::vector<char>( utf16ptr, utf16ptr+sizeof(utf16) ); const unsigned int utf32 = 0x0000FEFF; const char* utf32ptr = reinterpret_cast<const char*>( &utf32 ); if ( sizeof(ValueType) == 4 ) return std::vector<char>( utf32ptr, utf32ptr+sizeof(utf32) ); assert( 0 ); return std::vector<char>(); } int main() { std::wstring kyrill = L"..."; std::ofstream file( "test.txt", std::ios::binary ); std::vector<char> bom = getByteOrderMark<wchar_t>(); file.write( &bom[0], bom.size() ); file.write( reinterpret_cast<const char*>(kyrill.c_str()), kyrill.length()*sizeof(wchar_t) ); }
-
Wieso bietet C++ denn Mittel wie wofstream und wstring an, wenn man es am Ende (wie Bandestrand gezeigt hat) selbst implementieren muss

-
Weil es einen Unterschied gibt zwischen "wie und wo speichere ich etwas" (std::wstring etc.) und "wie und wo gebe ich etwas aus" (std::wcout, std::fstream, etc.).
Simon
-
C++ bietet dir die Infrastruktur, aber wenn du die Stream-Operatoren benutzt, dann benötigst du auch ein entsprechendes Locale um die Zeichenkette entsprechend zu speichern. Und dummerweise wurden keine Locales für die Standardzeichensätze spezifiziert. Eine Standardbibliothek welche diese mitliefert ist die von Dinkumware, allerdings kostet die ein bischen was.