التعامل مع الملفات في C++

التعامل مع الملفات في C++

تعني معالجة الملفات القراءة من الملفات والكتابة إليها (مثل .txt .csv وما إلى ذلك) باستخدام الفئات التي توفرها مكتبة C++ القياسية.

  • تعمل البرامج في ذاكرة الوصول العشوائي (RAM) مما يعني أن البيانات موجودة فقط أثناء تشغيل البرنامج وعندما ينتهي البرنامج يتم فقدان كافة البيانات الموجودة في ذاكرة الوصول العشوائي (RAM) تلقائيًا.
  • تسمح معالجة الملفات بتخزين البيانات في الذاكرة الثانوية (مثل HDD أو SSD) بحيث يمكن حفظها بشكل دائم ويمكن حفظها والوصول إليها حتى بعد انتهاء البرنامج.
  • بالنسبة لعمليات الملفات، يوفر C++ فئات دفق الملفات في ملف رأس مثل ofstream ifstream fstream.

فتح ملف

قبل القراءة من ملف أو الكتابة إليه، نحتاج أولاً إلى فتحه. يؤدي فتح ملف إلى تحميل هذا الملف في ذاكرة الوصول العشوائي (RAM). في لغة C++، نفتح ملفًا عن طريق إنشاء دفق له باستخدام ملف com.fstream فئة تمثل دفق الملف، أي دفق الإدخال والإخراج إلى الملف.

C++
   fstream     str  (  'filename.ext'       mode  );   

أين

  • شارع: الاسم المعطى للتيار
  • اسم الملف: اسم الملف
  • وضع : يمثل الطريقة التي سنتفاعل بها مع الملف.

أوضاع فتح الملفات

يشير وضع فتح الملف إلى أن الملف مفتوح للقراءة أو الكتابة أو الإلحاق. فيما يلي قائمة بجميع أوضاع الملفات في C++:

وضع وصف
دائرة الرقابة الداخلية::في الملف مفتوح للقراءة. إذا كان الملف غير موجود، فستفشل عملية الفتح.
دائرة الرقابة الداخلية::خارج ملف مفتوح للكتابة: يدعم المخزن المؤقت للتيار الداخلي عمليات الإخراج.
دائرة الرقابة الداخلية::ثنائي يتم تنفيذ العمليات في الوضع الثنائي بدلاً من النص.
دائرة الرقابة الداخلية::أكلت يبدأ موضع الإخراج في نهاية الملف.
دائرة الرقابة الداخلية::التطبيق تتم جميع عمليات الإخراج في نهاية الملف بإلحاق محتوياته الموجودة.
دائرة الرقابة الداخلية :: الجذع يتم تجاهل أي محتويات كانت موجودة في الملف قبل فتحه.

على سبيل المثال إذا أردنا فتح الملف للقراءة نستخدم وضع الفتح التالي:

C++
   fstream     filein  (  'file.txt'       ios  ::  in  );   

وبالمثل إذا أردنا فتح الملف للكتابة نستخدم ما يلي:

C++
   fstream     fileout  (  'file.txt'       ios  ::  out  );   

يمكن أيضًا دمج هذه الأوضاع باستخدام عامل التشغيل OR (|). على سبيل المثال، يمكنك فتح دفق الملف في وضع القراءة والكتابة كما هو موضح:

C++
   fstream     str  (  'file.txt'       ios  ::  in     |     ios  ::  out  );   

إذا كان الملف المفتوح في وضع الكتابة غير موجود، فسيتم إنشاء ملف جديد. ولكن إذا كان الملف المفتوح في وضع القراءة غير موجود، فلن يتم إنشاء ملف جديد وسيتم طرح استثناء

تدفقات الملفات الأخرى

com.fstream ليس دفق الملفات الوحيد الذي يوفره C++. هناك نوعان من التدفقات المتخصصة:

  • com.ifstream : لتقف على دفق ملف الإدخال. وهو ما يعادل فتح fstream في دائرة الرقابة الداخلية::في وضع.
  • ofstream : لتقف على دفق ملف الإخراج. وهو ما يعادل فتح fstream في دائرة الرقابة الداخلية::خارج وضع.

الأوضاع المذكورة أعلاه هي الأوضاع الافتراضية لهذه التدفقات. لا يمكن تغيير هذه الأوضاع ولكن يمكن دمجها مع أوضاع أخرى. الآن بالنسبة للإدخال يمكننا أيضًا استخدام ifstream كما هو موضح:

C++
   ifstream     filein  (  'file.txt'  );   

وبالمثل بالنسبة للإخراج:

C++
   ofstream     fileout  (  'file.txt'  );   

كتابة البيانات إلى ملف

بمجرد فتح الملف في وضع الكتابة باستخدام أي منهما com.fstream أو ofstream يمكننا إجراء عملية الكتابة بطريقة مماثلة كما هو الحال مع استخدام cout < < operator.

C++
   #include          using     namespace     std  ;   int     main  ()     {      // Open a file      ofstream     file  (  'GFG.txt'  );          // Write the string to the file      file      < <     'Welcome to GeeksforGeeks.'  ;      return     0  ;   }   
يكتبGFG.text

قراءة البيانات من الملف

بمجرد فتح الملف في وضع القراءة باستخدام إما fstream أو ifstream يمكننا إجراء عملية الكتابة بطريقة مشابهة كما هو الحال مع cin باستخدام >> المشغل.

C++
   #include          using     namespace     std  ;   int     main  ()   {      // Open a file in read mode      ifstream     file  (  'GFG.txt'  );      string     s  ;      // Read string from the file      file     >>     s  ;      cout      < <     'Read String: '      < <     s  ;      return     0  ;   }   


الإخراج

 Read String: Welcome  

هذا لديه نفس المشكلة مثل سين. يتم أخذ الإدخال فقط حتى حرف المسافة البيضاء الأول. لتجنب هذا يمكننا استخدام خط الحصول () وظيفة كما هو مبين:

C++
   #include          using     namespace     std  ;   int     main  ()   {      // Open a file in read mode      ifstream     file  (  'GFG.txt'  );      string     s  ;      // Read string from the file      getline  (  file       s  );      cout      < <     'Read String: '      < <     s  ;      return     0  ;   }   


الإخراج

 Read String: Welcome to GeeksforGeeks.  

إغلاق الملف

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

في C++، يتم إغلاق الملفات باستخدام يغلق() وظيفة العضو الموجودة في جميع تدفقات الملفات.

C++
   #include          using     namespace     std  ;   int     main  ()   {      // Open a file in read mode      ifstream     file  (  'GFG.txt'  );      string     s  ;      // Read string from the file      getline  (  file       s  );      cout      < <     'Read String: '      < <     s  ;      // Close the file      file  .  close  ();      return     0  ;   }   


الإخراج

 Read String: Welcome to GeeksforGeeks.  

أخطاء في التعامل مع الملفات

يمكن أن تحدث العديد من أنواع الأخطاء المختلفة أثناء معالجة الملفات مثل عدم العثور على الملف ممتلئًا بالقرص وما إلى ذلك. يجب أن تتوقع برامجنا أخطاء شائعة ويجب أن تكون قادرة على التعامل معها بشكل صحيح. فيما يلي بعض الأخطاء الشائعة التي يمكن أن تحدث أثناء معالجة الملفات:

فشل فتح الملف

من الممكن أن تكون هناك حالات لا يتم فيها فتح الملف لأسباب مختلفة مثل عدم وجوده أو أن البرنامج ليس لديه الإذن بفتحه وما إلى ذلك. في هذه الحالة يمكننا استخدام الأمر is_open() وظيفة العضو في فئات دفق الملف للتحقق مما إذا كان الملف قد تم فتحه بنجاح أم لا.

C++
   #include          using     namespace     std  ;   int     main  ()     {      fstream     file  (  'nonexistent_file.txt'       ios  ::  in  );      // Check if the file is opened      if     (  !  file  .  is_open  ())     {      cerr      < <     'Error: Unable to open file!'      < <     endl  ;      return     1  ;      }      file  .  close  ();      return     0  ;   }   


الإخراج

 Error: Unable to open file!  

الفشل في قراءة/كتابة البيانات

خطأ شائع آخر هو الفشل في قراءة البيانات أو كتابتها لأسباب مثل الوضع غير الصحيح وما إلى ذلك. في هذه الحالة يمكننا التحقق من صحة العمليات بعد كل محاولة قراءة/كتابة. على سبيل المثال، يمكن التحقق من صحة القراءة باستخدام getline() كما يظهر:

C++
   #include          using     namespace     std  ;   int     main  ()     {      fstream     file  (  'GFG.txt'       ios  ::  out  );      if     (  !  file  .  is_open  ())     {      cerr      < <     'Error: Unable to open file!'      < <     endl  ;      return     1  ;      }      string     line  ;          // Checking if getline() read successfully or not      if     (  !  getline  (  file       line  ))      cerr      < <     'Error: Failed to read data'      < <     endl  ;      file  .  close  ();      return     0  ;   }   


الإخراج

 Error: Failed to read data  

خطأ في نهاية الملف (EOF).

قد تؤدي محاولة القراءة بعد نهاية الملف إلى حدوث خطأ EOF. يمكن أن يحدث هذا عندما لا تتحقق من نهاية الملف قبل القراءة. يمكننا التحقق من استخدام EOF eof() وظيفة العضو.

C++
   #include          using     namespace     std  ;   int     main  ()   {      ifstream     file  (  'GFG.txt'  );      if     (  !  file  .  is_open  ())      {      cerr      < <     'Error: Unable to open file!'      < <     endl  ;      return     1  ;      }      string     line  ;      while     (  getline  (  file       line  ))      cout      < <     line      < <     endl  ;      // Check for eof      if     (  file  .  eof  ())      cout      < <     'Reached end of file.'      < <     endl  ;      else      cerr      < <     'Error: File reading failed!'      < <     endl  ;      file  .  close  ();      return     0  ;   }   


الإخراج

 Reached end of file.  

لاحظ أننا قمنا أيضًا بالتحقق من صحة عملية القراءة قبل التحقق من EOF كـ خط الحصول () سوف يعود فقط nullptr حتى لو فشلت القراءة لأي سبب من الأسباب.

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

في C++ يمكننا أيضًا التعامل مع الملفات الثنائية التي تخزن البيانات بتنسيق خام. لقراءة وكتابة البيانات الثنائية يجب استخدام دائرة الرقابة الداخلية::ثنائي إشارة عند إنشاء/فتح ملف ثنائي.

الكتابة في ملف ثنائي

لكتابة البيانات إلى ملف ثنائي، نحتاج أولاً إلى فتح الملف أو إنشاؤه فيه دائرة الرقابة الداخلية::ثنائي وضع.

C++
   #include         #include         #include          using     namespace     std  ;   int     main  ()   {      string     str     =     'Welcome to GeeksForGeeks'  ;      // Open a binary file for writing      ofstream     file  (  'fileBin.bin'       ios  ::  binary  );      // Check if the file is open      if     (  !  file  )      {      cerr      < <     'Error opening the file for writing.'  ;      return     1  ;      }      // Write the length of the string (size) to file first      size_t     strLength     =     str  .  length  ();      file  .  write  (  reinterpret_cast   <  const     char     *>  (  &  strLength  )     sizeof  (  strLength  ));      // Write the string to the binary file      file  .  write  (  str  .  c_str  ()     strLength  );      // Close the file      file  .  close  ();      return     0  ;   }   


الإخراج

writeBinaryملف ثنائي

القراءة من الملف الثنائي

مثلما نفتح ملفًا في الوضع الثنائي لكتابة البيانات لقراءة البيانات من ملف ثنائي، يجب علينا فتح الملف في وضع القراءة باستخدام دائرة الرقابة الداخلية::في .

بناء الجملة:

C++
   fstream     fileInstance  (  'fileName.bin'       ios  ::  in  |     ios  ::  binary  );   
C++
   #include         #include         #include          using     namespace     std  ;   int     main  ()   {      string     str  ;      // Open the binary file for reading      fstream     file  (  'fileBin.bin'       ios  ::  in     |     ios  ::  binary  );      // Check if the file is open      if     (  !  file  )      {      cerr      < <     'Error opening the file for reading.'  ;      return     1  ;      }      // Read the length of the string (size) from the file      size_t     strLength  ;      file  .  read  (  reinterpret_cast   <  char     *>  (  &  strLength  )     sizeof  (  strLength  ));      // Allocate memory for the string and read the data      char     *  buffer     =     new     char  [  strLength     +     1  ];     // +1 for the null-terminator      file  .  read  (  buffer       strLength  );      // Null-terminate the string      buffer  [  strLength  ]     =     ''  ;      // Convert the buffer to a string      str     =     buffer  ;      // Print file data      cout      < <     'File Data: '      < <     str  ;      delete  []     buffer  ;      file  .  close  ();      return     0  ;   }   


الإخراج

 File Data: Welcome to GeeksForGeeks  

عمليات الملفات الأخرى

يمكننا أيضًا إجراء المزيد من العمليات لمعالجة ملف من برنامج C++ الخاص بنا. بعض عمليات الملفات الشائعة هي:

  • برنامج C++ لحذف ملف
  • إلحاق سلسلة في ملف موجود
  • نسخ ملف واحد إلى ملف آخر
إنشاء اختبار