Binär-Dateien

Hallo Leute,

Ich spiele mich gerade damit, Zahlen in eine Binär-Datei zu schreiben und wieder auszulesen (nur Integer, keine Floats). Das klappt auch mit positiven Zahlen ganz gut, aber mit negativen nicht.

Bei *.wav (im Header) und bei *.mid (generell) sind ja nur Positive drin. Haben die einen guten Grund, das so zu machen?
Sind die negativen Zahlen generell ein Problem?

Einen Artikel dazu gibt es hier
http://de.wikipedia.org/wiki/Bin%C3%A4rdatei
ist aber nicht sehr aufschlußreich.
Mein Code ist etwas lange zum drucken (zwei Klassen, lesen und schreiben, plus Test-cpp).

lg
Martin B

Hallo Leute,

Ich spiele mich gerade damit, Zahlen in eine Binär-Datei zu
schreiben und wieder auszulesen (nur Integer, keine Floats).
Das klappt auch mit positiven Zahlen ganz gut, aber mit
negativen nicht.

  1. Frage, wie schreibst du, wie liest du ?
  2. welche Programmiersprache

Bei *.wav (im Header) und bei *.mid (generell) sind ja nur

Aha , wenn das mal so ist :smile:

Positive drin. Haben die einen guten Grund, das so zu machen?
Sind die negativen Zahlen generell ein Problem?

?? Negative Zahlen sind nie ein problem ?.

Aber #FF kan sowohl MINUS als auch PLUSS sein.
Wenn es pluss ist, verabredet man das es kein Bit für das vorzeichen gibt.
8 bits = 0-255

Wenn minus , verabredet man das das erste bit das vorzeichen darstellt.
7 bits = 0-127 , 8tes Bit = 1 minus / 0 pluss .
somit ergibt sich der wert -127 bis +127 …

Es liegt also daran wie die verabredung beim schreiben getroffen wurden.

Schreibe ich z.b. in die datei FFFF , also 2 mal 8 bits , dann kann ich sie auf 2 weisen lesen.

ohne vorzeichen bit lese ich 255 für die ersten beiden FF und nochmal 255 für die zweiten FF.

mit vorzeichen bit lese ich -127 für die ersten FF und -127 für die zweiten FF.

der lesende muss also wissen wie der schreibende vorgegangen ist und was er schreiben wollte.

Zuletzt sei gesagt eigentlich rechnet der computer eh immer nur pluss :smile: Und hat nur 0 und 1 und kein -1 zustand :smile:

Einen Artikel dazu gibt es hier
http://de.wikipedia.org/wiki/Bin%C3%A4rdatei
ist aber nicht sehr aufschlußreich.
Mein Code ist etwas lange zum drucken (zwei Klassen, lesen und
schreiben, plus Test-cpp).

Ich empfehle mal zahlenbereiche von variablen typen.
hier erklärt wie das mit dem Bit ist eines vorzeichen typs :smile: http://tutorial.schornboeck.net/vartypen.htm

lg
Martin B

Hallo RakonDark,

  1. Frage, wie schreibst du, wie liest du ?

Ich habe ein Klasse „BinaryWriter“, welche Daten binär kodiert und mit FILE* in eine Binärdatei schreibt.
Eine zweite Klasse „BinaryParser“ liest sie dann wieder aus. Dann macht man noch zwei Funktionen zum Testen.
Ich möchte eine eigenes Dateiformat für (von Hand gemalte) Bilder entwickeln, mit Marken ähnlich HTML, aber eben binär kodiert.

  1. welche Programmiersprache

C++.

?? Negative Zahlen sind nie ein problem ?.

Gut zu wissen. Ich hatte ewig Ärger damit, d.h., ich kriegte andere Zahlen zurück, als ich gespeichert hatte.
Ich sehe gerade, daß ich jetzt das nicht mal hinkriege :

#include 
#include 
#include 

int main()
{
 // das heutige Datum in ein "long" packen:
 // long box = 0;
 unsigned long box = 0;

 // 10.4.2008
 box |= 10;
 box |= (4 



> Aber #FF kan sowohl MINUS als auch PLUSS sein.  
> der lesende muss also wissen wie der schreibende vorgegangen  
> ist und was er schreiben wollte.


Danke für die vielen Tipps, aber das ist mir schon klar. Die negativen int's machten bei mir halt ewig Ärger.

Es gibt also wohl Dateiformate, bei denen negative Werte vorgesehen sind, richtig?

Tschuldige die verspätete Antwort. Ich kann den Code schon posten, wenn gewünscht, ist aber etwas lange.
lg
Martin B

Es gibt also wohl Dateiformate, bei denen negative Werte
vorgesehen sind, richtig?

??? wie datei formate ???

Es gibt variablen typen die sind nur positiv oder positiv und negativ ,demendsprechend schreibt man die bytes und liest sie wieder.

wenn ich 1000001 schreibe und der leser liest 1000001 dann muss der leser wissen wie er das lesen soll , im positiven wertebereich oder im negativ positiv wertebereich.

Ich glaub bei dir ist irgentwie der zahlenbereich nicht richtig definiert. Also deine Logik lässt wohl keine negativen zahlen zu und schreibt bzw liest nur im positiven Bereich.

Du kannst den code gern posten, aber ich glaub bei dir fehlt einfach nur grundwissen um binär lesen schreiben und was ist ein binär wert eigentlich.

weil 1000001 könnt ja auch für einen buchstaben stehen.

nur der parser bestimmt also was er wie lesen muss und das anhand der schreib reihenfolge . bzw Anahand der Tags in deinem Beispiel.
z.b.
lese 4 bytes , bilde daraus eine zahl mit vorzeichen
lese 2 bytes , bilde daraus eine zahl ohne vorzeichen
lese 2 bytes , bilde daraus eine Zeichen im ASCII Statz

der lesende muss also wissen was wann geschrieben wurde.

Hallo RakonDark,

Es gibt also wohl Dateiformate, bei denen negative Werte
vorgesehen sind, richtig?

??? wie datei formate ???

naja, *.avi, *.bmp, *.xls usw.

Ich glaub bei dir ist irgentwie der zahlenbereich nicht
richtig definiert. Also deine Logik lässt wohl keine negativen
zahlen zu und schreibt bzw liest nur im positiven Bereich.

Aktuell habe ich im Code nur positive Zahlen, das ist schon so. Klappt ja auch viel besser.

Du kannst den code gern posten,

bitte, ist unten angehaengt.

aber ich glaub bei dir fehlt
einfach nur grundwissen

Uuuh, das weiss ich alles. Das Problem ist: ich kriege die negative Zahlen falsch retour.

lg
Martin B

////////////////////////////////////

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
char buf[256];
#define LOG\_DATEI ("app.log")

template 
class Vector
{
 std::vector v;
 int i;
 int size;

public:
 Vector() : i(0), size(0)
 {}
 Vector& operator BIN\_UCHAR\_STACK;
#define FLOAT\_FACTOR 10000

ULONG getFileSize(FILE \*fpIn)
 {
 fseek(fpIn, 0, SEEK\_END);
 ULONG fileSize = ftell (fpIn);
 fseek(fpIn, 0, SEEK\_SET);

 return (ULONG)fileSize;
 }

class BinaryWriter
{
public:
 BinaryWriter(bool littleEndian);
 ~BinaryWriter();
 long getSize() {return Keep.getSize();}
 void setValue(ULONG &temp, uchar which, ULONG wert);

 // Anwender muss die Zahl bitweise auf "ULONG num" kopieren...
 // "ULONG lo = -24;" würde heissen, das '-' kommt ganz links hin...!
 // "num" wird nachher auf Null zurueckgesetzt.
 int integer(ULONG &num, int numBytes);
 int double\_(double &dou);
 BinaryWriter& operator 4) ? (4) : (numBytes);
 ULONG mask;

 if (littleEndian)
 {
 shifter = 0;
 for (i=0; i \> shifter);
 Keep -1; i--, shifter-=8)
 {
 mask = (0xff \> shifter);
 Keep integer (num, 4);

 num |= (diff);
 this-\>integer (num, 4);

 return 0;
}

BinaryWriter& BinaryWriter::operator \> (uchar uch);
};

BinaryParser::BinaryParser(CC file, bool littleEndian\_) :
 // data (openFile(file, 0, "rb")),
 data (0),
 littleEndian (littleEndian\_),
 i (0),
 fileSize(0)
{
 FILE \*bin = fopen(file, "rb");
 fileSize = getFileSize(bin);
 data = new uchar[fileSize + 2];
 assert (data);

 fread(data, sizeof(char), fileSize, bin);
 data[fileSize + 1] = 0;

 if (2 cout fertig." \> (uchar uch)
{ 
 uch = data[i++];
 return \*this;
}

int BinaryParser::someChars(std::string &get, const int numBytes)
{
 get.erase();
 for (int j=0; j 4) ? (4) : (numBytes);

 num = 0;
 if (littleEndian)
 {
 shifter = 0;
 for (j=0; j -1; i++, j--, shifter-=8)
 {
 uch = data[i]; 
 if (uch) {num |= (uch integer(ul, 4);
 dou += ul;

 // the floats:
 this-\>integer(ul, 4);
 dou += ul / FLOAT\_FACTOR;

 return 0;
}

//////////////////////////////////////////

// bin\_pars.cpp

class Punkt
{ 
 public: 
 long x, y;

 Punkt() {}
 Punkt(long x\_, long y\_) : x(x\_), y(y\_) {}
 Punkt(LPARAM l) : x(l & 0xFFFF), y((l & 0xFFFF0000) \>\> 16) {}
 // int getBinaryLen() {return 4;} 
 int getBinaryData(BinaryWriter &Bywr)
 {
 // schreibt zwei UINT's:
 ULONG u = 0;
 u |= x; // copy
// OK, da muss ich noch "ausmisten, :smile:" 
 if (x = -128) {u &= ~(0xffffff = -128) {u &= ~(0xff x y 

Also

in die Writer::double

dort muss nach negativ / positiv unterschieden werden
und dementsprechen das vorzeichen gesetzt werden,

das ganze dann zusammenbasteln
, dementsprechend wieder auseinander frimeln beim Parser (also gugen was vorzeichenbit sacht) :smile:

 (although formally undefined behavior) is to convert the address
of the double to a uint64\_t\* (or the address of the float to a
uint32\_t\*), and output that in the usual way, e.g.:

 dest.put( value \>\> 56 ) ;
 dest.put( value \>\> 48 ) ;
 dest.put( value \>\> 40 ) ;
 dest.put( value \>\> 32 ) ;
 dest.put( value \>\> 24 ) ;
 dest.put( value \>\> 16 ) ;
 dest.put( value \>\> 8 ) ;
 dest.put( value ) ;

To be totally generic, of course, you need to extract the
different parts of the double, and reassemble them. Something
like:

 bool isNeg = source ( value ) ;
 dest.put( (isNeg ? 0x80 : 0x00) | exp \>\> 4 ) ;
 dest.put( ((exp \> 48) & 0x0F) ) ;
 dest.put( mant \>\> 40 ) ;
 dest.put( mant \>\> 32 ) ;
 dest.put( mant \>\> 24 ) ;
 dest.put( mant \>\> 16 ) ;
 dest.put( mant \>\> 8 ) ;
 dest.put( mant ) ; 

siehe auch http://en.wikipedia.org/wiki/IEEE_754#Double-precisi…