Speichern von Zahlen groesser als 255 in mehreren Ints



  • vielleicht, aber unions werden immernoch unterstützt bzw. sind bestandteil von C++.



  • randa schrieb:

    Das BMP-Format beinhaltet keine Daten, die größer 255 sind, es sei denn die File Header. Wozu musst du das im Zusammenhang mit BMP machen?

    eben genau um den Header geht es.
    Ich schreibe jetzt selber BMP's und dazu benutze ich die ganzen fstream-funktionen.
    d.h:
    ofstream ofile1("hallo.bmp", ios::out);
    ofile1<<HEADER_TEIL1(z.B. int Breite);

    Das Problem: in bmp's ist jedes int auf vier chars verteilt, jedes short auf 2 und so weiter. wenn ich aber ein int in einen ofstream schreibe, dann wird es als string gespeichert und nicht als binärzahl.
    deswegen die zahl-zerhäckselung.

    @Mis2Com(Eisflamme): Vielen dank! In bitverschiebungen bin ich noch nicht so bewandert!
    Hier (falls es noch jemanden interessiert) die gegenfunktion:

    short int qchar2short (qchar qc1)
    {
    int i1 = qc1.bytes[0]; 
    int i2 = (qc1.bytes[1] << 8); 
    return i1+i2; 
    }
    

    mfg und vielen dank an alle,
    chris90



  • Lass die bitschieberei ... die bringt dir nix an der stelle ....

    was willst du genau ?

    du hasst nen schort ...

    denn schort streamst du in eine Textdatei ?

    was soll der short dir genau bringen .... angenommen dein short ist ishort = 65, was soll in der Textdatei stehen ???
    65
    oder
    A
    ???
    Ich vermute aber mal ganz stark, das deine bmp datei keine Textdatei sein soll ... also wuerde ich den stream mal als binaeren stream verwenden ....

    ios::binary Opens the file in binary mode (the default is text mode)

    Ciao ...



  • chris90 schrieb:

    Ich schreibe jetzt selber BMP's und dazu benutze ich die ganzen fstream-funktionen.
    d.h:
    ofstream ofile1("hallo.bmp", ios::out);
    ofile1<<HEADER_TEIL1(z.B. int Breite);

    😃 👍
    Du bist kreativ 😉
    die lösung des Problems:

    ofstream file ("xxx.bmp", std::ios::out);
    file.write (...);
    

    Edit: Also

    file.write (reinterpret_cast<char*> (data), sizeof (Data));
    


  • 1. @RHBaum:

    RHBaum schrieb:

    was soll der short dir genau bringen .... angenommen dein short ist ishort = 65, was soll in der Textdatei stehen ???
    65
    oder
    A
    ???

    DAS funktioniert ja auch. Wenn ich ein char vereinbare und ihm dann einen Integerwert gebe und das char in die file schreibe, speichert er ihn als binärwert. Aber das problem ist, dass ein short ja auch größer als 255 sein kann. Was mache ich z.B. wenn mein short 5000 ist? Dann brauche ich mindestens 2 character um es zu halten. Und in meinem fall geht es dadrum.

    Ich vermute aber mal ganz stark, das deine bmp datei keine Textdatei sein soll ... also wuerde ich den stream mal als binaeren stream verwenden ....
    Zitat:
    ios::binary Opens the file in binary mode (the default is text mode)

    Ich muss dich enttäuschen, aber ios::binary hat keinen Einfluss auf die Write-Funktion (hab's getestet).

    2. @randa:

    file.write (reinterpret_cast<char*> (data), sizeof (Data));
    

    Erste Frage: ist "data" gleich "Data"?
    Zweite Frage: Kann es sein, dass da noch irgendwo ein fehler drin ist? Bei mir gibt's einen laufzeit-absturz zu dieser stelle!!

    vielen dank, mfg,
    chris90

    PS:

    randa schrieb:

    Du bist kreativ 😉

    Klar: Was einem an Erfahrung fehlt, muss man mit verückten ideen ausgleichen 😃



  • ofstream myfile("xxx.bmp", std::ios::binary);
    
    short ishort = 257; 
    
    myfile << ishort;
    

    Glaub ned das der da ned binaer schreibt ....

    Glaub du hasst nen winzig kleines Verstaendniss Problem mit c++ streams 😃
    solltest dir echt mal naeher anschauen.
    Zum Beispiel sollte man bei outputstreams (ofstream) ned noch std::ios::out angeben muessen 🙂 Man kann natuerlich , aber ist wie mit fahradfahren und treten, wenns bergab geht.

    des weiteren:
    streams ueberschreiben die die << und >> operatoren, jeweils wie sie denken das es eben am wahrscheinlichsten ist, wie mans verwendet.

    Nen Textstream denkt immer fuer dich, dass wenn du nen char reinstreamst, dass es sich um einen Buchstaben handelt. myfile << static_cast<char>(65); wird er dir als A interpretieren und folgerichtig binaer 65 ins file schreiben.

    dagegen gibt es (noch) keine 32 bit zeichentypen, also wird er nen int/long immer als Zahl interpretieren ....
    also wenn dem das mit der Zeichenumwandlung eintrichtern willst, brauchst z.b den char nur auf nen long hochzucasten ....
    myfile << static_cast<long>(65); wird er dir also mit nem "65" im textfile quitieren. also

    ostream::write
    ostream& write( const char* pch, int nCount );

    ostream& write( const unsigned char* puch, int nCount );

    ostream& write( const signed char* psch, int nCount );

    Parameters

    pch, puch, psch

    A pointer to a character array.

    nCount

    The number of characters to be written.

    Remarks

    Inserts a specified number of bytes from a buffer into the stream. If the underlying file was opened in text mode, additional carriage return characters may be inserted. The write function is useful for binary stream output.

    wie du siehst, sollte der mode schon nen unterschied machen ....
    Da zeichenketten soweiso schon binaerformat sind, kannst die so nutzen ....

    Aber zugegeben, streams sind sehr "gewoehnugsbeduerftig". An vielen stellen setze ich auch noch die c-funktionen stattdessen ein, weil ich mir den aerger und das gecaste spare. Und printf & co sind manchmal echt pracktisch.

    Aber fuer dein Anwendungszweck sinds trotzdem gut geeignet, weil du die "probleme" relativ einfach umschiffen kannst.

    1. dein Header ist nen block aus Bytes. Behandle ihn doch auch so.

    Beispiel: dein "header" komplett ist 32 byte gross, und dein short (2byte) ist das 7. und 8. bit (also 6 und 7 auf mit Null begonnen).

    dann mach sowas

    char myheader[32] ; // gleich aufn stack anlegen, das ist schoen schnell 
    
    short & myshort(reinterpret_cast<short &>(myheader[6]));
    

    Nun hast deinen Header als Block vorliegen, und ne Referenz auf 2 byte in dem blosck als short, was willst mehr ....
    das ist userfreundlich und gleichzeitig performant ....

    das 7. und 8. byte kannst einfach ansprechen in dem auf die short ref zugreifst .... und raustreamen kannst das ganze in einem rutsch ....

    myshort = 258 // setzt das 6. byte in deinem header auf 2, und das 7. byte auf 1 (0x0102)
    
    ofstream file ("xxx.bmp", std::ios::binary);
    file << myheader; // streamt dir alles aufs mal raus ....
    

    schau dir zeiger und referenzen an, die sind fuer sowas, wenn mit bytebloecken arbeitest, eh unerlaesslich ...

    Ciao ...



  • chris90 schrieb:

    Erste Frage: ist "data" gleich "Data"?

    Ja, schreibfehler. Es muss einfach sizeof der zu schreibenden Variablen sein 😃

    Zweite Frage: Kann es sein, dass da noch irgendwo ein fehler drin ist? Bei mir gibt's einen laufzeit-absturz zu dieser stelle!!

    Hmm, bei reinterpret_cast musst du vorsichtig sein, wenn da irgendwas falsches gecastet wird, hast du ein Problem. Also ich habe ja bis jetzt noch kein Binärfile mit den streams geschrieben, nur Ascii. Aber schau dich mal bei google um, da findest du bestimmt irgendein Beispiel.
    Du solltest die Daten auch unbedingt einzeln in die Datei schreiben, wenn du einen Compiler hast, der dir die structs bzw. classes auf eine Größe optimiert, die ein vielfaches von zwei ist (wie z.B. VS). Da die File Header beide eine ungerade größe haben, würden sie beide "optimiert".

    Edit: Wie gesagt, ich weiß aus eigener erfahrung: Mit dem >> operator kriegst du nix vernünftiges aus ner Binärdatei raus.



  • wenn du einen Compiler hast, der dir die structs bzw. classes auf eine Größe optimiert

    Aehm wie meinst du das ?

    struct {
        char t1[27];
        char t2[122];
         } mystruct;
    
    std::cout << sizeof(mystruct);
    

    wuerde dir ned 149 zurueckgeben ?

    denk mal fuer pods optimiert der compiler sowieso ned ...
    Hatte mit dem VC++ eigentlich noch keine probleme mit ....

    Naja, und normalerweisse macht man sowas auch ned :

    MyClass m;
    
    ostream test;
    
    test.write(reinterpret_cast<char *>(&m),sizeof(MyClass ));
    

    sondern überlead den >> operator und schreibt die pods da einzeln ...

    und beim einlesen von pods aus nem binaerstream mittels >> hat ich auch noch keine probs ... was fuer eine STL-Impl verwendest du ?

    Ciao ...



  • ich glaub ich lag falsch, ein vielfaches von 32 Bits meinte ich, also dass es optimal für den Prozessor zu verdauen ist.

    Was das einlesen betrifft, so hatte ich schon ursprünglich vor, die File Header als ganze einzulesen per read, aber die Ergebnisse waren falsch.
    Mit Sicherheit kann ich dir sagen, dass das einlesen per >> bei mir mit der STL aus VC++ Net nicht funktioniert hat, aber ich wüsste nicht, warum meine STL anders sein sollte als andere. Du hast es doch nicht ernsthaft geschafft, Binärdateien mit >> auszulesen?



  • int Version;
    	bool bTemp;
    
    	ObjectLock(this);
    
    	if (bIsLoading)
    	{
    		stream >> Version;
    
    		switch(Version)
    		{
    		case 4:
    			stream >> m_byPass;
    		case 3:
    			stream >> m_bDisplayCumulativeMessages;
    		case 2:
    			stream >> m_nTag;
    			stream >> m_bOutputToTrace;
    		}
    
    		stream >> bTemp;
    		m_bPassThrough = bTemp ? 1 : 0;
    
    		UpdateView();
    	}
    
    	else
    	{
    		Version=4;
    		stream << Version;
    		stream << m_byPass;
    		stream << m_bDisplayCumulativeMessages;
    		stream << m_nTag;
    		stream << m_bOutputToTrace;
    
    		bTemp = (m_bPassThrough == 1);
    		stream << bTemp;
    	}
    

    Ist nen ausschnitt aus code, der bei uns sogar produktiv laeft ....
    ok, stream ist kein fstream direkt, sondern nur nen puffer, der aber irgendwann auch in nen file gelesen oder geschrieben wird ... theorethisch funkt das aber auch mit nem filestream direkt ....

    Ciao ....


Anmelden zum Antworten