die Bytes aus einem wstring auslesen
-
Hallo,
ich möchte einen Unicodestring speichern und habe Probleme dabei.Mit folgenden Konstrukt bekomme ich eine Datei hin die
erstmal die BOMn enthält.vector<unsigned short> text16; text16.push_back(0xfeff); // bom ofstream fs16("c:/utf16.txt", ios_base::out | ios_base::binary); fs16.write(reinterpret_cast<const char*>(&text16[0]), text16.size() * sizeof (unsigned short));jetzt habe ich eine Klasse die von std::wstring erbt
und wollte gern einen String in die Datei speichern.
Leider klappt das nicht.
Beim Betrachten mit einem Hex-Editor stelle ich fest das das zweite Byte nicht
korrekt gespeichert wird.Beim Speichern mit folgendem Code
std::fstream ziel("c:/unicode.txt",ios_base::out|ios_base::binary); char *pc = Global::Conv_pwc2pc(value); // unicode Signatur ziel << std::hex; ziel << 0xFFFE; ziel << "PC value: " << pc << "\n"; ziel << "RString value: "; ziel << value ; ziel << "\n"; ziel.close();wird die Signatur nicht korrekt abgelegt, außerdem der RString
weil der Operator << so überladen ist das die Adresse an der der RString liegt ausgegeben wird.Jetzt wollte ich die Bytes einzeln speichern, kann aber auf das zweite nicht korrekt zugreifen:
wstring tmp; char a[100]; for (int i=0; i<(value.size()); i++) { tmp = value.substr(i,1); wchar_t tmpwc= *tmp.c_str(); void *p = &tmp; char *pc = (char *) p; char a1,b,c; a1 = tmp[0]; b = tmp[1]; // c = tmp._Ptr; // hier steht es drin, leider kein Zugriff a[i*2] = *pc; a[i*2+1] = *(pc+sizeof (char)); a1 = a[i*2]; b = a[i*2+1]; } fs16.write(a,value.size() * sizeof (unsigned short));im wchar sind die Bytes noch richtig drin, wie bekomme ich sie einzeln heraus ?
oder wie kann ich die Adresse bekommen ab der die Bytes im wstring gespeichert sind ?
Viel
-
Rufus schrieb:
wstring tmp; char a[100]; for (int i=0; i<(value.size()); i++) { tmp = value.substr(i,1); wchar_t tmpwc= *tmp.c_str(); void *p = &tmp; char *pc = (char *) p; char a1,b,c; a1 = tmp[0]; b = tmp[1]; // c = tmp._Ptr; // hier steht es drin, leider kein Zugriff a[i*2] = *pc; a[i*2+1] = *(pc+sizeof (char)); a1 = a[i*2]; b = a[i*2+1]; } fs16.write(a,value.size() * sizeof (unsigned short));was für eine vergewaltigung der sprache.
-
ich habe es erstmal so gemacht:
// String der nur aus dem ersten Zeichen besteht wstring tmp; wchar_t tmpwc; // hier wird die Zeichenkette gespeichert char *b = new char[value.size()*2]; for (int i=0; i<(value.size()); i++) { tmp = value.substr(i,1); tmpwc= *tmp.c_str(); b[i*2] = tmpwc; b[i*2+1] = tmpwc >> 8; } fs16.write(b,value.size() * sizeof (unsigned short)); delete(b);das muß aber auch noch besser gehen !
-
wieso verwendest du nicht einfach einen wfstream? und wie ist value definiert?
-
Rufus schrieb:
das muß aber auch noch besser gehen !
Geht es.
Eine BOM ist nichts anderes als ein Zeichen; nämlich U+FEFF "zero width no-break space".
Und wenn Du dieses und einen wstring in ein File schreiben möchtest, so kannst Du das mit einen wofstream tun. Etwa so:#include <iostream> #include <fstream> #include <string> int main() { using namespace std; const wchar_t BOM = 0xfeff; // Unicode-Zeichen "zero width no-break space" wofstream file( "output.txt" ); wstring s = L"Hello World"; if( file << BOM << s ) { cout << "alles Ok" << endl; } return 0; }In welcher Weise die Zeichen dann in Bytes umgewandelt werden ist Sache der Facette codecvt des unter dem ofwstream liegenden streambuf's.
GGf. kann man diese mit
file.rdbuf()->pubimbue( ... )austauschen. Eine Facette für die Konvertierung nach UTF8 findet man z.B. hier.
Gruß
Werner