Verstehe Unicode nicht
-
Bei mir klappt das mit Unicode überhaupt nicht. Ich habe folgenden Quelltext:
`#include<iostream>
#include<string>
using namespace std;
main()
{
wstring test = "
さくら";cout << test << endl;
cout << test[0] << test[1] << test[2] << endl;
}`
Abgespeichert als UTF-8 gibt folgende Compilerfehler:
test.cpp: In functionint main()':test.cpp:7: error: conversion from
const char[10]' to non-scalar typestd::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >' requestedtest.cpp:8: error: no match for 'operator<<' in 'std::cout << test'
/usr/lib/gcc/x86_64-pc-linux-gnu/3.4.6/include/g++-v3/bits/ostream.tcc:63: note: candidates are: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>&(*)(std::basic_ostream<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-pc-linux-gnu/3.4.6/include/g++-v3/bits/ostream.tcc:74: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ios<_CharT, _Traits>&(*)(std::basic_ios<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-pc-linux-gnu/3.4.6/include/g++-v3/bits/ostream.tcc:86: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::ios_base&(*)(std::ios_base&)) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-pc-linux-gnu/3.4.6/include/g++-v3/bits/ostream.tcc:121: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-pc-linux-gnu/3.4.6/include/g++-v3/bits/ostream.tcc:155: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-pc-linux-gnu/3.4.6/include/g++-v3/bits/ostream.tcc:98: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(bool) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-pc-linux-gnu/3.4.6/include/g++-v3/ostream:180: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-pc-linux-gnu/3.4.6/include/g++-v3/ostream:191: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-pc-linux-gnu/3.4.6/include/g++-v3/ostream:195: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-pc-linux-gnu/3.4.6/include/g++-v3/ostream:206: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-pc-linux-gnu/3.4.6/include/g++-v3/bits/ostream.tcc:179: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long long int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-pc-linux-gnu/3.4.6/include/g++-v3/bits/ostream.tcc:214: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long long unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-pc-linux-gnu/3.4.6/include/g++-v3/bits/ostream.tcc:238: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(double) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-pc-linux-gnu/3.4.6/include/g++-v3/ostream:221: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(float) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-pc-linux-gnu/3.4.6/include/g++-v3/bits/ostream.tcc:261: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long double) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-pc-linux-gnu/3.4.6/include/g++-v3/bits/ostream.tcc:284: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(const void*) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-pc-linux-gnu/3.4.6/include/g++-v3/bits/ostream.tcc:307: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_streambuf<_CharT, _Traits>*) [with _CharT = char, _Traits = std::char_traits<char>]`
Abgespeichert als UTF-16, UTF-32, UCS-2 oder UCS-4 gibt es folgende Compilerfehler:
`test.cpp:1: error: stray '\255' in program
test.cpp:1: error: stray '\254' in program
test.cpp:1: error: invalid token
test.cpp:1:4: warning: null character(s) ignored
test.cpp:1:6: warning: null character(s) ignored
test.cpp:1: error: `i' does not name a type
test.cpp:1:8: warning: null character(s) ignored
[...]
test.cpp:2:3: warning: null character(s) ignored
test.cpp:2:4: invalid preprocessing directive #i
test.cpp:2:5: warning: null character(s) ignored
[...]
test.cpp:5:3: warning: null character(s) ignored
test.cpp:5: error: `m' does not name a type
test.cpp:5:5: warning: null character(s) ignored
[...]
test.cpp:7:33: warning: null character(s) ignored
test.cpp:7:36: warning: null character(s) preserved in literal
test.cpp:7:45: warning: null character(s) ignored
[...]
test.cpp:11:1: warning: null character(s) ignored
test.cpp:11:2: warning: no newline at end of file`
Wenn ich statt wstring einfach string nehme und das ganze als UTF-8 abspeichere, kompiliert es zwar, aber die Ausgabe ist nur:
さくら
さAusgabe sollte aber sein:
さくら
さくらWenn ich nun ustring verwende:
`#include<iostream>
#include<glibmm.h>
using namespace std;
using Glib::ustring;
main()
{
ustring test = "さくら";
cout << test << endl;
cout << test[0] << test[1] << test[2] << endl;
}`
und das ganze als UTF-8 abspeichere kompiliert es zwar auch, ich bekomme aber folgenden Laufzeitfehler:
`terminate called after throwing an instance of 'Glib::ConvertError'
zsh: abort ./a.out`
Könnt ihr mir helfen?
-
Ups. Den letzten quellcode hat das Forum kaputt gemacht. So ist es richtig:
`#include<iostream>
#include<glibmm.h>
using namespace std;
using Glib::ustring;
main()
{
ustring test = "
さくら";cout << test << endl;
cout << test[0] << test[1] << test[2] << endl;
}`
-
#include<iostream> #include<string> using namespace std; int main() { std::string test = "你好"; cout << test << endl; for(size_t i = 0; i < test.size(); ++i) std::cout << "0x" << std::hex << static_cast<unsigned>(static_cast<unsigned char>(test[i])) << '\n'; }# g++ -Wall -W -std=c++98 foo.cpp # ./a.out 你好 0xe4 0xbd 0xa0 0xe5 0xa5 0xbdDas erste Beispiel (mit wstring) funktioniert so nicht, da wstring-Literale mit einem L beginnen (also anstelle "foo", L"foo") und du solltest wcout benutzen. Denk dran, dass du auch dein Terminal entsprechend einstellen musst oder ein locale bei wcout setzen!
warum das ustring Beispiel nicht funktioniert, weiß ich jetzt nicht. Habe aber auch kein glibmm da, um das zu überprüfen.
-
UNICODE Strings sollte man IMO nicht in C++ Source Files packen. Zumindest nicht wenn man möchte dass alles reibungslos funktioniert.

-
Und wie würdest du dann obiges Beispiel schreiben?
-
rüdiger schrieb:
Sie ist doch nicht fest, wenn ich damit UTF-16 Strings darstelle. Ansonsten ist wchat_t einfach nicht breit genug unter den meisten Windows-Compilern, um alle Zeichen darzustellen, die das System darstellen kann.
Ja, laut Standard muss wchar_t jedoch den maximalen Code-Point fassen können. Das heißt, es ist ganz klar als feste Zeichenbreite definiert. Wäre dem nicht so, wären die ganzen Standard-Konveriertungsfunktionen zwischen breiten Zeichen (wchar_t()) und Multibyte-Kodierungen (mittels char) auch relativ sinnlos.
Aber selbst wenn die Standards in dem Punkt gebrochen werden, ändert das nichts daran, dass zwei Bytes für die mit Abstand meisten Zeichen ausreichen. In der gewöhnlichen Praxis wird man also vermutlich nie einen Unterschied zwischen UTF-16 und UCS-2 bei internen Repräsentationen bemerken. (Was natürlich nicht davon ablenken soll, dass man damit nicht auf Nummer sicher geht.)wcout kann übrigens mitunter ziemlich (Standard-)locale-resistent sein. Sicher ist man dagegen mit File-Streams (wofstream) - die haben mir in dem Punkt noch keinen Ärger gemacht.
-
edocinU schrieb:
Und wie würdest du dann obiges Beispiel schreiben?
Keine Ahnung was du da für Zeichen benutzt hast. Aber UCS und Unicode gibt man am besten in dieser Form ein:
L"\u06A1\u0609\u06A0"Um genau zu sein: U-Escapes. Weiß nicht ob das U jetzt für UCS oder Unicode steht.
-
C++ ist noch nicht dazu geeignet, Unicode Strings zu verarbeiten. Vielleicht ändert sich das ja mit C++0x. Aber bis dahin würde ich an deiner Stelle einfach Perl verwenden. Damit geht das einfacher und unkompliziert:
`#!/usr/bin/perl
use Encode;
binmode(STDOUT, ":utf8");
my $test = decode_utf8("
さくら");print($test, "\n");
print(substr(test, 1, 1), substr($test, 2, 1), "\n");`
Ausgbe wie erwartet:
さくら
さくら

-
-------------------------- /| /| | | ||__|| | Trolle bitte | / O O\__ nicht | / \ füttern! | / \ \ | / _ \ \ ---------------------- / |\____\ \ || / | | | |\____/ || / \|_|_|/ | __|| / / \ |____| || / | | /| | --| | | |// |____ --| * _ | |_|_|_| | \-/ *-- _--\ _ \ // | / _ \\ _ // | / * / \_ /- | - | | * ___ c_c_c_C/ \C_c_c_c____________
-
Artchi schrieb:
-------------------------- /| /| | | ||__|| | Trolle bitte | / O O\__ nicht | / \ füttern! | / \ \ | / _ \ \ ---------------------- / |\____\ \ || / | | | |\____/ || / \|_|_|/ | __|| / / \ |____| || / | | /| | --| | | |// |____ --| * _ | |_|_|_| | \-/ *-- _--\ _ \ // | / _ \\ _ // | / * / \_ /- | - | | * ___ c_c_c_C/ \C_c_c_c____________-------------------------- /| /| | | ||__|| | Trolle bitte | / O O\__ nicht | / \ füttern! | / \ \ | / _ \ \ ---------------------- / |\____\ \ || / | | | |\____/ || / \|_|_|/ | __|| / / \ |____| || / | | /| | --| | | |// |____ --| * _ | |_|_|_| | \-/ *-- _--\ _ \ // | / _ \\ _ // | / * / \_ /- | - | | * ___ c_c_c_C/ \C_c_c_c____________
-
@Artchi:
Es ist leider wirklich so, dass sich C++ (im Gegensatz zu z.B. Perl) mit Unicode noch recht schwer tut. Selbst mit Glib::ustring scheint es ja nicht richtig zu funktionieren (auch wenn ich es selbst noch nicht getestet habe).
-
Hihi.
Perl, PHP, Java etc. setzen im Normalfall C oder C++ Libraries ein um mit Unicode zu arbeiten. Oft ist es einfach die (leider sehr schrottige) ICU.
Und die kann man genausogut in C++ verwenden.