Frage

Ich habe mehrere Ints geschrieben, char [] s und die so in eine Datendatei mit Binary in C #. Lesen Sie die Datei wieder in (in C #) mit Binary, kann ich perfekt alle Teile der Datei neu zu erstellen.

versucht jedoch, sie zu lesen zurück in mit C ++ liefert einige beängstigende Ergebnisse. Ich war mit fstream um zu versuchen, die Daten zu lesen zurück und die Daten wurden nicht richtig zu lesen. In C ++, hat ich einen fstream mit ios::in|ios::binary|ios::ate und gebrauchtem seekg bis zu meinem Standort Ziel. I lesen dann die nächsten vier Bytes, die als die ganze Zahl geschrieben wurden „16“ (und liest korrekt in C #). Diese liest als 1244780 in C ++ (nicht die Speicheradresse, ich geprüft). Warum wäre das? Gibt es ein Äquivalent zu Binary in C ++? Ich bemerkte es auf Msdn erwähnt, aber das ist Visual C ++ und intellisense sieht nicht einmal, wie C ++, für mich.

Beispiel-Code für das Schreiben der Datei (C #):

    public static void OpenFile(string filename)
    {
        fs = new FileStream(filename, FileMode.Create);
        w = new BinaryWriter(fs);

    }

    public static void WriteHeader()
    {
        w.Write('A');
        w.Write('B');
    }

    public static byte[] RawSerialize(object structure)
    {
        Int32 size = Marshal.SizeOf(structure);
        IntPtr buffer = Marshal.AllocHGlobal(size);
        Marshal.StructureToPtr(structure, buffer, true);
        byte[] data = new byte[size];
        Marshal.Copy(buffer, data, 0, size);
        Marshal.FreeHGlobal(buffer);
        return data;
    }

    public static void WriteToFile(Structures.SomeData data)
    {
        byte[] buffer = Serializer.RawSerialize(data);
        w.Write(buffer);
    }

Ich bin mir nicht sicher, wie ich Ihnen die Datendatei zeigen.

Beispiel für die Daten zurück (C #) zu lesen:

        BinaryReader reader = new BinaryReader(new FileStream("C://chris.dat", FileMode.Open));
        char[] a = new char[2];
        a = reader.ReadChars(2);
        Int32 numberoffiles;
        numberoffiles = reader.ReadInt32();
        Console.Write("Reading: ");
        Console.WriteLine(a);
        Console.Write("NumberOfFiles: ");
        Console.WriteLine(numberoffiles);

Das habe ich in C ++ ausführen möchten. Erster Versuch (nicht auf dem ersten integer):

 fstream fin("C://datafile.dat", ios::in|ios::binary|ios::ate);
 char *memblock = 0;
 int size;
 size = 0;
 if (fin.is_open())
 {
  size = static_cast<int>(fin.tellg());
  memblock = new char[static_cast<int>(size+1)];
  memset(memblock, 0, static_cast<int>(size + 1));

  fin.seekg(0, ios::beg);
  fin.read(memblock, size);
  fin.close();
  if(!strncmp("AB", memblock, 2)){ 
   printf("test. This works."); 
  }
  fin.seekg(2); //read the stream starting from after the second byte.
  int i;
  fin >> i;

Edit:. Es scheint, dass egal welche Position ich „seekg“ verwenden, um, ich den exakt gleichen Wert erhalte

War es hilfreich?

Lösung

Sie erkennen, dass ein Zeichen 16 Bits in C # sind eher als die 8 es in der Regel in C. Dies ist, weil ein char in C # entwickelt wird Unicode-Text zu verarbeiten, anstatt Rohdaten. Daher wird in Unicode führt die Binary Zeichen schriftlich unter Verwendung wird geschrieben, anstatt roh Bytes.

Dies könnte Sie führen den Versatz der ganzen Zahl falsch zu berechnen. Ich empfehle Ihnen, einen Blick auf die Datei in einem Hex-Editor, und wenn Sie nicht das Problem, die Datei arbeiten können, veröffentlichen und den Code hier.

EDIT1
In Bezug auf Ihrem C ++ Code, verwenden Sie nicht den Operator >> von einem binären Stream zu lesen. Verwendung lesen () mit der Adresse des int, den Sie lesen möchten.

int i;
fin.read((char*)&i, sizeof(int));

EDIT2
gehen zu führen ist auch in undefiniertem Verhalten von einem geschlossenen Strom zu lesen. Sie können nicht fin.close () aufrufen und dann erwarten, dass noch in der Lage sein, von ihm zu lesen.

Andere Tipps

Dies kann oder nicht mit dem Problem in Zusammenhang stehen kann, aber ...

Wenn Sie die Binary erstellen, wird standardmäßig chars in UTF-8 zu schreiben. Dies bedeutet, dass einige von ihnen länger sein kann als ein Byte, Abwerfen Ihr sucht.

Sie können dies vermeiden, indem Sie das 2 Argument Konstruktor mit der Codierung angeben. Eine Instanz von System.Text.ASCIIEncoding wäre das gleiche wie das, was C / C ++ Verwendung standardmäßig aktiviert.

Es gibt viele Dinge in Ihrem C ++ falsch läuft Schnipsel. Sie sollten nicht mit formatiert Lesen Binär-Lese mischen:

  // The file is closed after this line. It is WRONG to read from a closed file.
  fin.close();

  if(!strncmp("AB", memblock, 2)){ 
   printf("test. This works."); 
  }

  fin.seekg(2); // You are moving the "get pointer" of a closed file
  int i;

  // Even if the file is opened, you should not mix formatted reading
  // with binary reading. ">>" is just an operator for reading formatted data.
  // In other words, it is for reading "text" and converting it to a 
  // variable of a specific data type.
  fin >> i;

Wenn es keine Hilfe ist, ging ich durch, wie die Binary schreibt Daten hier .

Es ist schon eine Weile, aber ich werde es zitieren und hoffe, es ist richtig:

  • wird Int16 als 2 Bytes geschrieben und gepolstert.
  • wird Int32 als Little Endian geschrieben und mit Nullen aufgefüllt
  • Floats sind komplizierter: es nimmt den Float-Wert und Dereferenzierungen es, die Speicheradresse bekommen Inhalt, die eine hexadezimale
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top