ما هي أفضل طريقة قراءة مزدوجة من الملفات الثنائية التي تم إنشاؤها في C ؟

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

  •  08-07-2019
  •  | 
  •  

سؤال

برنامج C يبصق على التوالي الزوجي في ملف ثنائي.أتمنى أن تقرأ لهم في بيثون.حاولت استخدام struct.unpack('d',f.read(8))

تحرير:لقد استعملت ما يلي في ج إلى كتابة عشوائية عدد مزدوج

r = drand48();
fwrite((void*)&r, sizeof(double), 1, data);

الأخطاء التي يتم إصلاحها الآن ولكن أنا لا يمكن قراءة القيمة الأولى.على كل 0.000..رقم يقرأ كما 3.90798504668055 ولكن البقية على ما يرام.

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

المحلول

وأعتقد أنك تقرأ في الواقع عدد صحيح، ولكن يتم الحصول على الخلط من جانب العرض. عندما قرأت عدد من ملفك المقدمة، أحصل على "3.907985046680551e-14" - وهذا هو تقريبا ولكن ليس تماما صفر (0.000000000000039 في شكل موسع). وأظن كود C الخاص بك هو مجرد طباعته مع أقل دقة من الثعبان هو.

[عدل] لقد حاولت فقط قراءة الملف في C، وأحصل على نفس النتيجة (على الرغم من أقل قليلا الدقة: 3.90799e 14) (باستخدام printf ( "٪ ز"، فال))، لذلك أعتقد إذا كانت هذه القيمة غير صحيحة، حدث على الجانب الكتابة، بدلا من القراءة.

نصائح أخرى

فأرجو توضيح "لم تعمل" ؟ هل الأمر تحطم ؟ هل البيانات يخرج خطأ ؟ ما الذي حدث فعلا ؟

إذا كان الأمر تحطمت:

  • يرجى حصة الخطأ إخراج الأمر

إذا كانت البيانات ببساطة خرج الخطأ:

  • هل الأنظمة التي تخلق وقراءة البيانات لها نفس endianness?إذا كان واحد هو big-endian و الآخر endian طفيف, ثم تحتاج إلى تحديد endianness التحويل في شكل سلسلة.

  • إذا كان endianness من اثنين من أجهزة الكمبيوتر هي نفسها كيف كانت البيانات المكتوبة على الملف ، بالضبط?هل تعلم ؟ إذا كنت تفعل, ثم ما قيمة مكتوبة إلى ملف وماذا كانت قيمة غير صحيحة لديك ؟

أولا، هل حاولت المخلل ؟ وقد أظهرت أحدا أي رمز بيثون بعد ... وفيما يلي بعض التعليمات البرمجية للقراءة في ثنائي في بيثون:

import Numeric as N
import array
filename = "tmp.bin"
file = open(filename, mode='rb')
binvalues = array.array('f')
binvalues.read(file, num_lon * num_lat) 
data = N.array(binvalues, typecode=N.Float)   

file.close()

وأين و هنا حددت الدقة واحدة، 4 بايت العائمة، وأرقام. البحث مهما كان حجمها بياناتك في الدخول واستخدام ذلك.

لبيانات غير ثنائي يمكن أن تفعل شيئا بسيطا مثل هذا:

   tmp=[]
   for line in open("data.dat"):
                tmp.append(float(line))
  • f.read(8) قد يعود أقل من 8 بايت
  • البيانات قد محاذاة مختلفة و/أو endianness:

    >>> for c in '@=<>':
    ...     print repr(struct.pack(c+'d', -1.05))
    ...
    '\xcd\xcc\xcc\xcc\xcc\xcc\xf0\xbf'
    '\xcd\xcc\xcc\xcc\xcc\xcc\xf0\xbf'
    '\xcd\xcc\xcc\xcc\xcc\xcc\xf0\xbf'
    '\xbf\xf0\xcc\xcc\xcc\xcc\xcc\xcd'
    >>> struct.unpack('<d', '\xbf\xf0\xcc\xcc\xcc\xcc\xcc\xcd')
    (-6.0659880001157799e+066,)
    >>> struct.unpack('>d', '\xbf\xf0\xcc\xcc\xcc\xcc\xcc\xcd')
    (-1.05,)
    

و <م> أفضل طريقة سيكون لاستخدام ملف نصي ASCII:

<اقتباس فقرة>   

0.0
  3.1416
  +3.90798504668055

وفي أنه سيكون المحمولة والعمل مع أي نوع من عائمة تنفيذ النقطة إلى حد ما.

وقراءة البيانات الثنائية الخام من عنوان ذاكرة double ليست المحمولة على الإطلاق، وكان من المحتم أن تفشل في بعض تنفيذ مختلف.

ويمكنك بالطبع استخدام تنسيق ثنائي الاكتناز، ولكن جهاز محمول كتابة C وظيفة في هذا الشكل لا تبدو المتكررة على الإطلاق.

وعلى أقل تقدير، يجب أن تكون محاطة التعليمات البرمجية عن طريق سلسلة من المؤسسة الدولية للعلوم / ifdefs التحقق من أن التمثيل ذكرى doubles المستخدمة من قبل الجهاز الحالي يطابق تماما واحد المتوقع من قبل مترجم Python.

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

وهذا من شأنه أن يكون <م> بلدي تعريف "أفضل".

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top