bitoperationen mit char und ofstream



  • hallo,
    ich bin gerade ein wenig dabei mit bitoperatoren rumzuspielen...
    ich wollte ein simples komprimierungsprogramm schreiben, dessen prinzip darauf beruht, lediglich 32 zeichen darzustellen und somit pro buchstabe lediglich 5 bit benötigt.
    daraus folgt, dass man für 8 buchstaben nur 5 chars benötigt.
    mit meinem programm wollte ich nun eine datei mit dem inhalt "abc" komprimieren.
    heraus kam eine datei mit 0 byte inhalt

    ich vermute, dass es beim schreiben oder bei der zuweisung der bits an die chars der fehler auftritt...

    könnt ihr mir sagen, ob das folgende korrekt ist?

    //bool b[40] enthält die 5 bits der kodierten zeichen
    	char ch[5];
    	for (int i=0; i<5; i++){ch[i] = '\0';}
    	for (int i=0, j=0, k=7; j<40; j++, k--)
    	{
    		if (k == -1){k = 7;}
    		i = j/8;
    		ch[i] += (b[j]<<k);//ch[i] bekommt seine 8 bits zugewiesen (links angefangen)
    	}
    
    	ofstream write;
    	write.open(pathwrite, ios_base::out|ios_base::app);
    	write << ch;//ch wird geschrieben
    	write.close();
    

  • Mod

    Funktioniert bei mir ganz wunderbar. Zumindest wenn ich dein Programm zu was compilierbarem ergänze:

    bool b[40] = {1,1,0,0,1,1,0,0,
                    0,0,1,1,0,0,1,1,
                    1,0,1,0,1,0,1,0,
                    1,1,1,1,1,1,1,1,
                    0,0,0,0,0,0,0,0
      };
        char ch[5];
        for (int i=0; i<5; i++){ch[i] = '\0';}
        for (int i=0, j=0, k=7; j<40; j++, k--)
        {
            if (k == -1){k = 7;}
            i = j/8;
            ch[i] += (b[j]<<k);//ch[i] bekommt seine 8 bits zugewiesen (links angefangen)
        }
    
        cout<<static_cast<int>(ch[0])<<endl;
        cout<<static_cast<int>(ch[1])<<endl;
        cout<<static_cast<int>(ch[2])<<endl;
        cout<<static_cast<int>(ch[3])<<endl;
        cout<<static_cast<int>(ch[4])<<endl;
    

    Kommen bei dir vielleicht Nullzeichen raus? Die würden nämlich beim Schreiben mittels Operator << das Ende eines C-Strings markieren.

    P.S.: Wenn du std::bitset benutzt, kannst du dir alle Bitoperationen sparen.



  • 1.) Dateim im Binaermodus oeffnen und mittels write schreiben.
    2.) Du kannst nur Blockweise schreiben. Der kleinste Block ist aber 1 Byte gross. D.h. du musst dir was ueberlegen, wie du bei z.B. zwei Buchstaben die 3 Bit des zweiten Buchstaben noch in das erste Byte des ersten schiebst.
    3.) Neben std::bitset gibts es auch noch std::vector<bool>.



  • knivil schrieb:

    2.) Du kannst nur Blockweise schreiben. Der kleinste Block ist aber 1 Byte gross. D.h. du musst dir was ueberlegen, wie du bei z.B. zwei Buchstaben die 3 Bit des zweiten Buchstaben noch in das erste Byte des ersten schiebst.

    das hab ich schon gelöst.

    seppj:
    mit cout funzt es bei mir auch, nur nicht mit
    ofstream write;
    write.open(blub);
    write << ch;
    write.close();



  • das hab ich schon gelöst.

    Dann lies dir nochmal 1.) durch fuer deine anderen Probleme. Wo versetzt du deinen ofstream in Binaermodus? Wo nutzt du die Methode write?

    PS: Methoden werden mit Verben benannt, Objekte mit Nomen. Ein Objekt mit write zu betiteln ist eher unguenstig. Besser ist vielleicht file oder out oder ... .



  • ahh, ich denke es klappt!!!
    dankE!!!

    worum geht das denn mit out.write(ch, 5) aber nicht mit out << ch ?



  • Weil ch als char* behandelt wird, d.h. er schreibt nich die 5 chars, sonder ab dem ersten, bis das erste \0 kommt. out << ch[0] << ch[1] << ...; hätte sicher auch geklappt.



  • und wenn in ch[1] Steuerzeichen enthalten sind ... Mit << schreibt man Text, mit write schreibt man Binaerdaten. Ist halt so. Eine kleine Inkonsistenz im Standard.



  • vielen dank!!!


Anmelden zum Antworten