العمليات الثنائية في ++C

c

العمليات الثنائية

يمكننا أن نخزن أرقاما علي الأقراص باستخدام العمليات المهيأة كما مر بنا حيث يحتل كل رقم في العدد بايتا مستقلا , ولكن إذا تطلب الأمر تخزين كم كبير من الأرقام , فالأنسب من ناحية الاقتصاد في مساحة الذاكرة أن تخزن علي الصورة الثنائية , وهي التي تخون بها في ذاكرة الرام بالجهاز . وفي الصورة الثنائية يخزن العدد الصحيح في 2 بايت ويخزن العدد الكسري في أربعة بايتات دائما , مهما كانت عدد أرقام العدد . بينما يتطلب عدد مثل 12345 إلي خمسة بايتات في الصورة النصية , ويتطلب عدد مثل 6.02314e13 إلي عشرة بايتات .

في البرنامج التالي نبين كيف نكتب مصفوفة من الأعداد في قرص , ثم نقرأها في ذاكرة مستخدمين النمط الثنائي . سوف نستخدم دالتين جديدتين , write() من دوال ofstream و read() من دوال ifstream . هاتان الدالتان تعتبران البيانات سلسلة من البايتات (من النوع char ) , لا يهمها علي أي وجه تكون تهيئتها , فالأولي ببساطة تملأ ذاكرة مرحلية بالبايتات , وتفرغها في القرص , ثم تقرأها الدالة الثانية . ولذا فإن كل دالة تأخذ معاملين لها , مؤشر (عنوان) الذاكرة المرحلية ] في البرنامج التالي المصفوفة [buff[] وحجمها [MAX] . ويجب أن يكون المؤشر محولا قسريا إلي char ] الصيغة buff(char*) [ , أما الحجم فهو عدد البايتات المطلوبة للبيانات , وليس عدد عناصر البيانات ذاتها ] يعبر عن ذلك في البرنامج بالصيغة [MAX* sizeof(int) .

 

binio.cpp


 


// binio.cpp


// binary input and output with integers


 


#include <fstream.h>                   // for file streams


#include <conio.h>


 


const int MAX = 100;                   // size of buffer


int buff[MAX];                         // buffer for integers


 


void main()


   {


   for(int j=0; j<MAX; j++)            // fill buffer with data


      buff[j] = j;                     // (0, 1, 2, ...)


                                       // create output stream


   ofstream os("edata.dat", ios::binary);


                                       // write to it


   os.write( (char*)buff, MAX*sizeof(int) );


   os.close();                         // must close it


 


   for(j=0; j<MAX; j++)                // erase buffer


      buff[j] = 0;


                                       // create input stream


   ifstream is("edata.dat", ios::binary);


                                       // read from it


   is.read( (char*)buff, MAX*sizeof(int) );


 


   for(j=0; j<MAX; j++)                // check data


      if( buff[j] != j )


         { cerr << "\nData is incorrect"; return; }


   cout << "\nData is correct";


   getche();


   }





تجد في هذا البرنامج أننا استخدمنا الصيغة ios::binary مع الدالتين المذكورتين للتبديل للنمط الثنائي , حيث إن الخيار المبدئي لهما هو النمط النصي . هذه الصيغة هي مثال لما يسمي " بتة النمط ''mode bit التي سوف نعرض لها لاحقا .



ويتيح النمط النصي شيئا من الحرية في التعامل مع البيانات . فمثلا , في النمط النصي يسجل المحرف ''\n'' في اثنين من البايتات واحدة تعبر عن العودة لأول السطر ] بالقيمة 10 في جدول الأسكي [ , والثانية للإنتقال لسطر جديد ] بالقيمة 13[ , قبل التسجيل علي القرص . ويجعل ذلك الملفات النصية المهيأة أيسر للقراءه بواسطة أوامر الدوس مثل الأمر type علي أن هذه الحرية تسبب بلبلة مع البيانات الثنائية , ولهذا السبب لابد من تبديل بته النمط .



وقد استخدمنا في هذا البرنامج الذات أمرا صريحا بإغلاق الملف , حيث يحتوي البرنامج بعد ذلك علي دالة القراءه , ويجب أن يغلق الملف قبل تشغيلها .

التسميات: