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


  • Mod

    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 !


  • Mod

    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


Anmelden zum Antworten