هل هناك ثنائي القريف في C ++ لقراءة البيانات المكتوبة من خط ثنائية في C #؟

StackOverflow https://stackoverflow.com/questions/1525580

سؤال

لقد كتبت العديد من Ints، char [] S وملف بيانات مع كتابة ثنائي في C #. قراءة الملف مرة أخرى في (في C #) مع BinaryReader، يمكنني إعادة إنشاء كل القطع من الملف تماما.

ومع ذلك، فإن محاولة قراءتها مرة أخرى مع C ++ غلة بعض النتائج المخيفة. كنت أستخدم FRSTREAM لإحاولة قراءة البيانات والبيانات لا تقرأ بشكل صحيح. في C ++، قمت بإعداد FRESTEAM ios::in|ios::binary|ios::ate وتستخدم البحث عن استهداف موقعي. ثم أقرأ البايت الأربعة المقبلة، والتي كتبت كعدد صحيح "16" (ويقرأ بشكل صحيح في C #). يقرأ هذا ك 1244780 في C ++ (وليس عنوان الذاكرة، قمت بفحصه). لماذا سيكون هذا؟ هل هناك ما يعادل ثنائي الثياب في C ++؟ لقد لاحظت أنها مذكورة على MSDN، ولكن هذا هو Visual C ++ والثانية الإنسانية لا يبدو وكأنه C ++، بالنسبة لي.

مثال رمز لكتابة الملف (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);
    }

لست متأكدا من كيفية إظهارك ملف البيانات.

مثال على قراءة البيانات مرة أخرى (C #):

        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);

هذا أريد أن أدفع في C ++. المحاولة الأولية (فشل في الاعتمادات الأولى):

 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;

تحرير: يبدو أنه بغض النظر عن الموقع الذي أستخدمه "البحث عن"، أتلقى نفس القيمة بالضبط.

هل كانت مفيدة؟

المحلول

أنت تدرك أن سحر هو 16 بت في C # بدلا من 8 عادة ما يكون في C. لذلك، سيؤدي كتابة الأحرف الكبيرة باستخدام كتاب ثنائي إلى يونيكون مكتوبا بدلا من البايت الخام.

قد يكون هذا قد يقودك لحساب إزاحة عدد صحيح بشكل غير صحيح. أوصي بإلقاء نظرة على الملف في محرر HEX، وإذا لم تتمكن من حل المشكلة نشر الملف والرمز هنا.

Edit1.
فيما يتعلق برمز C ++ الخاص بك، لا تستخدم المشغل >> لقراءة من دفق ثنائي. استخدم قراءة () مع عنوان INT الذي تريد قراءته إليه.

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

Edit2.
القراءة من دفق مغلق ستؤدي أيضا إلى سلوك غير محدد. لا يمكنك استدعاء FIN.Close () ثم لا تزال تتوقع أن تكون قادرا على القراءة منه.

نصائح أخرى

هذا قد يكون أو لا يرتبط بالمشكلة، ولكن ...

عند إنشاء BinaryWriter، فإنه الافتراضي في الكتابة charS في UTF-8. هذا يعني أن بعضها قد يكون أطول من بايت واحد، وإلقاء تسعى الخاص بك.

يمكنك تجنب ذلك باستخدام منشئ الحجة 2 لتحديد الترميز. مثال على ذلك System.Text.ASCIIEncoding سيكون هو نفسه ما يستخدمه C / C ++ بشكل افتراضي.

هناك الكثير من الأشياء التي تسير في مقتطف C ++ الخاص بك. يجب أن لا تخلط القراءة الثنائية مع القراءة المنسقة:

  // 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;

إذا كانت أي مساعدة، فقد مرت كيف يكتب ثنائي البيانات هنا.

لقد كان بعض الوقت، لكنني سأقتبسه ونأمل أن يكون دقيقا:

  • INT16 مكتوب ك 2 بايت ومبطن.
  • مكتوب Int32 بأنه نيدي صغير وصفر مبطن
  • يطفو أكثر تعقيدا: يتطلب الأمر قيمة تعويم و dereferences، والحصول على محتويات عنوان الذاكرة التي هي سداسي عشري
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top