تسلسل العمل مع الملف ج. إدخال البيانات من ملف وإخراجها إلى ملف. القراءة من والكتابة إلى ملف ثنائي

04.09.2023

في هذه المقالة سوف نتعلم كيفية قراءة البيانات من الملفات وكتابة المعلومات إلى الملفات في برامج C. الملفات في Cتُستخدم لحفظ نتيجة برنامج C واستخدامها عند بدء تشغيل البرنامج مرة أخرى. على سبيل المثال، يمكنك حفظ نتائج العمليات الحسابية وإحصائيات اللعبة.
للعمل مع الملفات في لغة C، تحتاج إلى تضمين مكتبة stdio.h
#يشمل
للعمل مع الملف في Cتحتاج إلى تحديد مؤشر للملف وفقًا للمثال
ملف * اسم مؤشر الملف؛
على سبيل المثال
ملف * زعنفة؛
يحدد مؤشر زعنفة إلى ملف
بعد ذلك، تحتاج إلى فتح الملف وربطه بمؤشر الملف. لفتح ملف في C للقراءة، استخدم الأمر
اسم مؤشر الملف = fopen("مسار الملف", "r");
على سبيل المثال الأمر التالي
fin = fopen("C:\\Users\\user\\Desktop\\data.txt"، "r");
سيتم فتح الملف data.txt الموجود على سطح المكتب على طول المسار C:\\Users\\user\\Desktop لمعرفة المسار إلى الملف، يمكنك تحديد الملف بالماوس، انقر فوق زر الفأرة الأيمن وحدد خصائص الملف. سيشير قسم الموقع إلى المسار إلى الملف. يرجى ملاحظة أنه في لغة C تتم الإشارة إلى المسار باستخدام خطين مائلين.
بعد العمل مع الملف في C، تحتاج إلى إغلاقه باستخدام الأمر
f Close (اسم مؤشر الملف)

قراءة المعلومات من ملف نصي في C

لتتمكن من قراءة الأحرف الروسية من ملف، تحتاج إلى تكوين العمل مع السيريلية باستخدام الأمر
setlocale(LC_ALL, "الروسية");

في هذه الحالة، يجب عليك تضمين #include في بداية البرنامج

عامل التشغيل fscanf()

لقراءة كلمة من الملف في Cيتم استخدام الأمر fscanf(). يشبه هذا الأمر أمر إدخال المعلومات من لوحة المفاتيح، فقط المعلمة الأولى هي مؤشر للملف
fscanf(file pointer,"%data input format1% data input format2...",&variable1,&variable2...);
على سبيل المثال الأمر
fscanf(fin,"%d%d%d",&a,&b,&c);
يقرأ سلسلة من ثلاثة متغيرات صحيحة من ملف مرتبط بمؤشر الملف fin
دعونا نلقي نظرة على مثال لبرنامج يقرأ منه ملف نصي data.txt الذي يحتوي على ثلاثة أعمدة من المعلومات الرقمية ويكتبها في صفائف. كل عمود من المعلومات له مصفوفته الخاصة. تفاصيل حول.
#يشمل
#يشمل
رئيسي()
(كثافة العمليات أ؛
كثافة العمليات ب؛
كثافة العمليات ج؛
كثافة العمليات أنا؛
// تحديد مؤشر للملف
ملف * زعنفة؛
// افتح الملف للقراءة
fin = fopen("C:\\Users\\user\\Desktop\\data.txt"، "r");
// القراءة سطرًا تلو الآخر من الملف
من أجل (i=0;i<3;i++)
{
// قراءة سلسلة من ثلاث قيم للملفات والكتابة إلى المصفوفات
fscanf(fin,"%d%d%d",&a[i],&b[i],&c[i]);
}
// عرض المصفوفات على الشاشة
من أجل (i=0;i<3;i++)
{
printf("%d %d %d ",a[i],b[i],c[i]);
}
getch();
// إغلاق الملف
fClose(fin);
}

قراءة المعلومات سطرًا تلو الآخر من ملف في SI الدالة fgets ()

يقرأ عامل التشغيل fscanf() كلمة من ملف، على سبيل المثال. إلى الفضاء الأول الذي واجهته.
لقراءة السطر بأكمله من ملف في لغة C، استخدم البناء
إذا (NULL! = fgets (متغير السلسلة، طول السلسلة، مؤشر الملف))
{
الإجراءات عند قراءة السطر
}

على سبيل المثال، برنامج C يقرأ سطرين من ملف ويعرضهما على الشاشة
#يشمل
#يشمل
#يشمل
رئيسي()
{
// تعيين متغيرات السلسلة
شار st1؛
شار st2؛
// تحديد مؤشر للملف
ملف * زعنفة؛
// إعداد العمل باستخدام الأبجدية السيريلية
setlocale(LC_ALL, "الروسية");
// افتح الملف للقراءة
fin = fopen("C:\\data.txt", "r");
// اقرأ السطر الأول من الملف
إذا (NULL ! = fgets (st1، 100، fin))
{
// عرض السلسلة على الشاشة
برينتف("%s ",st1);)
// اقرأ السطر الثاني من الملف
إذا (NULL != fgets (st2, 100, fin))
{
// عرض السلسلة على الشاشة
برينتف("%s ",st2);)
// أغلق الملف للقراءة
fClose(fin);
}

كتابة المعلومات إلى ملف نصي في C

لتسجيل البيانات إلى ملف في C، تحتاج إلى فتح الملف في وضع التسجيل
اسم مؤشر الملف = fopen("مسار الملف", "w");
للكتابة على سطر في ملف نصي، استخدم الأمر fprnitf()، وهو مشابه للأمر في لغة C، المعلمة الأولى فقط هي مؤشر للملف
fprintf (اسم مؤشر الملف،"% تنسيق الإدخال"، المتغيرات)؛
على سبيل المثال، كتابة قيمة المتغير a إلى الملف out.txt
أ = 10؛
fout = fopen("C:\\Users\\user\\Desktop\\out.txt"، "w");
fprintf(fout,"%d", a);

مثال لبرنامج C الذي يطلب رقمين ويكتب هذين الرقمين ومجموعهما في ملف out.txt

#يشمل
#يشمل

رئيسي()
(كثافة العمليات أ؛
كثافة العمليات ب؛
كثافة العمليات ج؛
ملف *fout؛
fout = fopen("C:\\Users\\user\\Desktop\\out.txt"، "w");
printf("أدخل الرقم الأول");
scanf("%d", &a);
printf("أدخل الرقم الثاني");
scanf("%d", &b);
ج=أ+ب;
fprintf(fout,"%d %d %d",a,b,c);
getch();
fClose(fout);
}

ولتسهيل الوصول إليها، يتم تخزين المعلومات الموجودة في أجهزة التخزين على شكل ملفات.

الملف عبارة عن منطقة محددة من الذاكرة الخارجية مخصصة لتخزين مجموعة من البيانات. البيانات الموجودة في الملفات ذات طبيعة متنوعة للغاية: برامج خوارزمية أو لغة الآلة؛ البيانات الأولية لتشغيل البرنامج أو نتائج تنفيذ البرنامج؛ نصوص مجانية؛ الصور الرسومية، الخ.

الدليل (مجلد، دليل) - مجموعة مسماة من البايتات على وسيط تخزين تحتوي على أسماء الدلائل الفرعية والملفات المستخدمة في نظام الملفات لتبسيط تنظيم الملفات.

نظام الملفاتيسمى الجزء الوظيفي من نظام التشغيل الذي ينفذ العمليات على الملفات. من أمثلة أنظمة الملفات FAT (FAT – جدول تخصيص الملفات)، NTFS، UDF (المستخدم على الأقراص المضغوطة).

هناك ثلاثة إصدارات رئيسية من FAT: FAT12، FAT16 وFAT32. وهي تختلف في عمق بت السجلات في بنية القرص، أي. عدد البتات المخصصة لتخزين رقم الكتلة. يُستخدم FAT12 بشكل أساسي للأقراص المرنة (حتى 4 كيلو بايت)، وFAT16 - للأقراص ذات السعة الصغيرة، وFAT32 - لمحركات أقراص FLASH عالية السعة (حتى 32 جيجابايت).

دعونا نلقي نظرة على بنية نظام الملفات باستخدام FAT32 كمثال.

هيكل الملف FAT32

تحتوي أجهزة الذاكرة الخارجية في نظام FAT32 على معالجة الكتلة بدلاً من معالجة البايت. تتم كتابة المعلومات على جهاز ذاكرة خارجي في كتل أو قطاعات.

القطاع هو الحد الأدنى من وحدة تخزين المعلومات القابلة للعنونة على أجهزة التخزين الخارجية. عادةً ما يتم تحديد حجم القطاع عند 512 بايت. لزيادة مساحة العناوين لأجهزة الذاكرة الخارجية، يتم دمج القطاعات في مجموعات تسمى مجموعات.

الكتلة هي اتحاد لعدة قطاعات، والتي يمكن اعتبارها وحدة مستقلة لها خصائص معينة. الخاصية الرئيسية للمجموعة هي حجمها، ويتم قياسه بعدد القطاعات أو عدد البايتات.

يحتوي نظام الملفات FAT32 على البنية التالية.

يتم ترقيم المجموعات المستخدمة لكتابة الملفات بدءًا من 2. وكقاعدة عامة، يتم استخدام المجموعة رقم 2 بواسطة الدليل الجذر، وبدءًا من المجموعة رقم 3 يتم تخزين مصفوفة البيانات. لا يتم تجميع القطاعات المستخدمة لتخزين المعلومات أعلى الدليل الجذر.
الحد الأدنى لحجم الملف المطلوب على القرص يتوافق مع مجموعة واحدة.

يبدأ قطاع التمهيد بالمعلومات التالية:

  • EB 58 90 - قفزة وتوقيع غير مشروط؛
  • 4D 53 44 4F 53 35 2E 30 MSDOS5.0;
  • 00 02 - عدد البايتات في القطاع (عادة 512)؛
  • 1 بايت – عدد القطاعات في المجموعة؛
  • 2 بايت – عدد القطاعات الاحتياطية.

بالإضافة إلى ذلك، يحتوي قطاع التمهيد على المعلومات المهمة التالية:

  • 0x10 (1 بايت) – عدد جداول FAT (عادة 2)؛
  • 0x20 (4 بايت) – عدد القطاعات الموجودة على القرص؛
  • 0x2С (4 بايت) - رقم مجموعة الدليل الجذر؛
  • 0x47 (11 بايت) - تسمية وحدة التخزين؛
  • 0x1FE (2 بايت) - توقيع قطاع التمهيد (55 AA).

يحتوي قطاع معلومات نظام الملفات على:

  • 0x00 (4 بايت) - التوقيع (52 52 61 41)؛
  • 0x1E4 (4 بايت) - التوقيع (72 72 41 61)؛
  • 0x1E8 (4 بايت) – عدد المجموعات الحرة، -1 إذا كان غير معروف؛
  • 0x1EC (4 بايت) – رقم آخر مجموعة مسجلة؛
  • 0x1FE (2 بايت) - التوقيع (55 AA).

يحتوي جدول FAT على معلومات حول حالة كل مجموعة على القرص. البايتتان السفليتان من جدول FAT تخزن F8 FF FF 0F FF FF FF FF (والتي تتوافق مع حالة المجموعتين 0 و1، الغائبتين فعليًا). علاوة على ذلك، تحتوي حالة كل مجموعة على رقم المجموعة التي يستمر فيها الملف الحالي أو المعلومات التالية:

  • 00 00 00 00 - المجموعة مجانية؛
  • FF FF FF 0F – نهاية الملف الحالي.
  • 8 بايت - اسم الملف؛
  • 3 بايت - امتداد الملف؛

يحتوي الدليل الجذر على مجموعة من سجلات المعلومات ذات 32 بت حول كل ملف، والتي تحتوي على المعلومات التالية:

عند العمل مع أسماء الملفات الطويلة (بما في ذلك الأسماء الروسية)، يتم ترميز اسم الملف باستخدام نظام الترميز UTF-16. في هذه الحالة، يتم تخصيص 2 بايت لترميز كل حرف. في هذه الحالة، يتم كتابة اسم الملف بالبنية التالية:

  • 1 بايت تسلسل؛
  • تحتوي 10 بايت على الأحرف الخمسة السفلية من اسم الملف؛
  • سمة 1 بايت؛
  • 1 بايت محجوز؛
  • 1 بايت - المجموع الاختباري لاسم DOS؛
  • 12 بايت تحتوي على الأحرف الثلاثة السفلية من اسم الملف؛
  • 2 بايت – رقم المجموعة الأولى؛
  • الأحرف المتبقية من الاسم الطويل.

العمل مع الملفات بلغة C

بالنسبة للمبرمج، يتم تمثيل الملف المفتوح كسلسلة من البيانات التي تتم قراءتها أو كتابتها. عندما يتم فتح ملف، فهو مرتبط بـ تيار الإدخال/الإخراج. تتم كتابة معلومات الإخراج إلى الدفق، وتتم قراءة معلومات الإدخال من الدفق.

عندما يتم فتح دفق للإدخال/الإخراج، فإنه يرتبط ببنية FILE القياسية، والتي تم تعريفها في stdio.h. تحتوي بنية FILE على المعلومات الضرورية حول الملف.

يتم فتح الملف باستخدام الدالة fopen()، والتي تُرجع مؤشرًا إلى بنية FILE التي يمكن استخدامها للعمليات اللاحقة على الملف.

ملف *fopen(الاسم، النوع)؛


الاسم - اسم الملف المراد فتحه (بما في ذلك المسار)،
type هو مؤشر لسلسلة من الأحرف التي تحدد كيفية الوصول إلى الملف:
  • "r" - افتح الملف للقراءة (يجب أن يكون الملف موجودًا)؛
  • "w" - فتح ملف فارغ للكتابة؛ إذا كان الملف موجودا، فستفقد محتوياته؛
  • "أ" - افتح الملف للكتابة حتى النهاية (للإلحاق)؛ يتم إنشاء الملف إذا لم يكن موجودا؛
  • "r+" - فتح الملف للقراءة والكتابة (يجب أن يكون الملف موجودًا)؛
  • "w+" - فتح ملف فارغ للقراءة والكتابة؛ إذا كان الملف موجودا، فستفقد محتوياته؛
  • "a+" - فتح الملف للقراءة والإلحاق، إذا كان الملف غير موجود، فسيتم إنشاؤه.

القيمة المرجعة هي مؤشر إلى الدفق المفتوح. إذا تمت مواجهة خطأ، يتم إرجاع NULL.

تقوم الدالة fClose() بإغلاق الدفق أو التدفقات المرتبطة بالملفات المفتوحة باستخدام الدالة fopen(). يتم تحديد الدفق المراد إغلاقه بواسطة وسيطة الدالة fclose().

قيمة الإرجاع: القيمة 0 إذا تم إغلاق الدفق بنجاح؛ EOF ثابت في حالة حدوث خطأ.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

#يشمل
إنت الرئيسي () (
ملف *fp;
اسم الحرف = "my.txt" ؛
إذا ((fp = fopen(name, "r" )) == NULL )
{
برينتف ( "فشل في فتح الملف");
getchar();
العودة 0؛
}
// نجح في فتح الملف
... // الإجراءات المطلوبة على البيانات
f Close(fp);
getchar();
العودة 0؛
}

قراءة حرف من ملف:

شار fgetc(تيار);


وسيطة الدالة هي مؤشر إلى دفق من النوع FILE. تقوم الدالة بإرجاع رمز حرف القراءة. إذا تم الوصول إلى نهاية الملف أو حدث خطأ، فسيتم إرجاع EOF الثابت.

كتابة رمز إلى ملف:

fputc(char,stream);

وسيطات الدالة هي حرف ومؤشر إلى دفق من النوع FILE. تقوم الدالة بإرجاع رمز حرف القراءة.

تشبه الدالتان fscanf() وfprintf() الدالتين scanf() وprintf()، لكنهما تعملان مع ملفات البيانات، ولها مؤشر ملف كوسيطة أولى لهما.

fscanf(stream, "InputFormat"، وسيطات);

تعمل معظم برامج الكمبيوتر مع الملفات، وبالتالي هناك حاجة لإنشاء الملفات وحذفها وكتابتها وقراءتها وفتحها. ما هو الملف؟ الملف عبارة عن مجموعة مسماة من وحدات البايت التي يمكن تخزينها على بعض أجهزة التخزين. حسنًا، أصبح من الواضح الآن أن الملف يعني تسلسلًا معينًا من وحدات البايت التي لها اسم فريد خاص بها، على سبيل المثال file.txt. لا يمكن وضع الملفات التي تحمل نفس الأسماء في نفس الدليل. لا يشير اسم الملف إلى اسمه فحسب، بل يشير أيضًا إلى امتداده، على سبيل المثال: file.txt وfile.dat ملفات مختلفة، على الرغم من أنها تحمل نفس الأسماء. يوجد شيء مثل اسم الملف الكامل - هذا هو العنوان الكامل لدليل الملف الذي يشير إلى اسم الملف، على سبيل المثال: D:\docs\file.txt. من المهم فهم هذه المفاهيم الأساسية، وإلا سيكون من الصعب العمل مع الملفات.

للعمل مع الملفات، تحتاج إلى تضمين ملف رأس . في يتم تعريف عدة فئات ويتم تضمين ملفات الرأس إدخال الملف و إخراج الملف.

يشبه إدخال/إخراج الملف الإدخال/الإخراج القياسي، والفرق الوحيد هو أن الإدخال/الإخراج يتم تنفيذه على ملف بدلاً من الشاشة. إذا تم تنفيذ الإدخال/الإخراج إلى الأجهزة القياسية باستخدام كائنات cin وcout، فمن أجل تنظيم إدخال/إخراج الملفات يكفي إنشاء كائناتك الخاصة التي يمكن استخدامها بشكل مشابه لمشغلي cin وcout.

على سبيل المثال، تحتاج إلى إنشاء ملف نصي وكتابة السطر "العمل مع الملفات في C++" فيه. للقيام بذلك عليك اتخاذ الخطوات التالية:

  1. إنشاء كائن من فئة الدفق ;
  2. ربط كائن فئة بالملف المراد الكتابة إليه؛
  3. كتابة سطر إلى ملف؛
  4. أغلق الملف.

لماذا من الضروري إنشاء كائن ofstream بدلاً من كائن ifstream؟ نظرًا لأنك تحتاج إلى الكتابة إلى ملف، وإذا كنت بحاجة إلى قراءة البيانات من ملف، فسيتم إنشاء كائن فئة ifstream.

// إنشاء كائن للكتابة في ملف الدفق /*اسم الكائن*/; // كائن من فئة الدفق

دعونا نسمي الكائن fout وهذا ما حصلنا عليه:

أوفستريم فوت؛

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

Fout.open("cppstudio.txt"); // ربط الكائن بالملف

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

فوت<< "Работа с файлами в С++"; // запись строки в файл

باستخدام عملية الدفق بالتزامن مع كائن fout، تتم كتابة سلسلة العمل مع الملفات في C++ إلى ملف. وبما أنه لم تعد هناك حاجة لتغيير محتويات الملف، فيجب إغلاقه، أي أنه يجب فصل الكائن عن الملف.

Fout.Close(); // أغلق الملف

النتيجة - تم إنشاء ملف باستخدام السطر "التعامل مع الملفات في C++".

يمكن دمج الخطوتين 1 و2، أي إنشاء كائن في سطر واحد وربطه بملف. يتم ذلك على النحو التالي:

Ofstream fout("cppstudio.txt"); // أنشئ كائنًا من فئة الدفق واربطه بملف cppstudio.txt

دعونا نجمع كل التعليمات البرمجية ونحصل على البرنامج التالي.

// file.cpp: يحدد نقطة الدخول لتطبيق وحدة التحكم. #تتضمن "stdafx.h" #تتضمن باستخدام مساحة الاسم الأمراض المنقولة جنسيا؛ int main(int argc, char* argv) ( ofstream fout("cppstudio.txt"); // إنشاء كائن من فئة التدفق للتسجيل وربطه بالملف cppstudio.txt fout<< "Работа с файлами в С++"; // запись строки в файл fout.close(); // закрываем файл system("pause"); return 0; }

يبقى التحقق من أن البرنامج يعمل بشكل صحيح، وللقيام بذلك، افتح الملف cppstudio.txt والنظر في محتوياته، ينبغي أن يكون -العمل مع الملفات في C++.

  1. إنشاء كائن من فئة ifstream وربطه بالملف الذي سيتم إجراء القراءة منه؛
  2. قراءة الملف؛
  3. أغلق الملف.
// file_read.cpp: يحدد نقطة الدخول لتطبيق وحدة التحكم. #تتضمن "stdafx.h" #تتضمن #يشمل باستخدام مساحة الاسم الأمراض المنقولة جنسيا؛ int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // العرض الصحيح لبرتقال الحروف السيريلية؛ // مخزن مؤقت للتخزين الوسيط للنص المقروء من ملف ifstream fin("cppstudio.txt") ; // فتح الملف لقراءة الزعنفة >><< buff << endl; // напечатали это слово fin.getline(buff, 50); // считали строку из файла fin.close(); // закрываем файл cout << buff << endl; // напечатали эту строку system("pause"); return 0; }

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

العمل مع الملفات في C++ للمتابعة، اضغط على أي مفتاح. . .

الشكل 1 - العمل مع الملفات في لغة C++

عمل البرنامج بشكل صحيح، ولكن هذا لا يحدث دائما، حتى لو كان كل شيء على ما يرام مع التعليمات البرمجية. على سبيل المثال، تم تمرير اسم ملف غير موجود إلى البرنامج أو كان هناك خطأ في الاسم. ماذا إذن؟ في هذه الحالة، لن يحدث شيء على الإطلاق. لن يتم العثور على الملف، مما يعني أنه لن يكون من الممكن قراءته. لذلك، سوف يتجاهل المترجم الأسطر التي يتم فيها العمل على الملف. ونتيجة لذلك، سيخرج البرنامج بشكل صحيح، ولكن لن يظهر أي شيء على الشاشة. يبدو أن هذا رد فعل طبيعي تمامًا لمثل هذا الموقف. لكن المستخدم البسيط لن يفهم ما يحدث ولماذا لم يظهر السطر من الملف على الشاشة. لذا، لتوضيح كل شيء، توفر لغة C++ مثل هذه الوظيفة - is_open()، والتي تُرجع قيمًا صحيحة: 1 - إذا تم فتح الملف بنجاح، 0 - إذا لم يتم فتح الملف. دعونا نعدل البرنامج من خلال فتح ملف، بحيث إذا لم يكن الملف مفتوحًا، يتم عرض الرسالة المقابلة.

// file_read.cpp: يحدد نقطة الدخول لتطبيق وحدة التحكم. #تتضمن "stdafx.h" #تتضمن #يشمل باستخدام مساحة الاسم الأمراض المنقولة جنسيا؛ int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // العرض الصحيح لبرتقال الحروف السيريلية؛ // مخزن مؤقت للتخزين الوسيط للنص المقروء من ملف ifstream fin("cppstudio.doc") // (لقد أدخلت اسم ملف غير صالح) إذا (!fin.is_open()) // إذا لم يكن الملف مفتوحًا cout<< "Файл не может быть открыт!\n"; // сообщить об этом else { fin >>برتقالي؛ // أحصى الكلمة الأولى من ملف cout<< buff << endl; // напечатали это слово fin.getline(buff, 50); // считали строку из файла fin.close(); // закрываем файл cout << buff << endl; // напечатали эту строку } system("pause"); return 0; }

وتظهر نتيجة البرنامج في الشكل 2.

لا يمكن فتح الملف! للمتابعة، اضغط على أي مفتاح. . .

الشكل 2 - العمل مع الملفات في لغة C++

وكما يتبين من الشكل 2، أبلغ البرنامج أنه كان من المستحيل فتح الملف. لذلك، إذا كان البرنامج يعمل مع الملفات، فمن المستحسن استخدام هذه الوظيفة، is_open()، حتى لو كنت متأكدًا من وجود الملف.

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

تحدد أوضاع فتح الملف كيفية استخدام الملفات. لتعيين الوضع، توفر فئة ios_base ثوابت تحدد وضع فتح الملف (انظر الجدول 1).

يمكن ضبط أوضاع فتح الملف مباشرةً عند إنشاء كائن أو عند استدعاء الدالة open() .

Ofstream fout("cppstudio.txt", ios_base::app); // افتح الملف لإلحاق المعلومات بنهاية الملف fout.open("cppstudio.txt", ios_base::app); // افتح الملف لإلحاق المعلومات بنهاية الملف

يمكن دمج أوضاع فتح الملف باستخدام عملية منطقية للبت أو| على سبيل المثال: ios_base::out | ios_base::trunc - يفتح ملفًا للكتابة بعد مسحه.

كائنات فئة ofstream، عندما تكون مرتبطة بالملفات، تحتوي بشكل افتراضي على أوضاع فتح الملف ios_base::out | ios_base::trunc . أي أنه سيتم إنشاء الملف في حالة عدم وجوده. إذا كان الملف موجودًا، فسيتم حذف محتوياته، وسيكون الملف نفسه جاهزًا للكتابة. كائنات فئة ifstream، عندما ترتبط بملف، يكون لها وضع فتح الملف الافتراضي ios_base::in - الملف مفتوح للقراءة فقط. يُطلق على وضع فتح الملف أيضًا اسم العلامة لسهولة القراءة، وسنستخدم هذا المصطلح في المستقبل. لا يسرد الجدول 1 كافة العلامات، ولكن يجب أن تكون هذه كافية للبدء.

لاحظ أن علامتي ate وapp متشابهتان جدًا في الوصف، فكلاهما يحرك المؤشر إلى نهاية الملف، لكن علامة التطبيق تسمح فقط بالكتابة حتى نهاية الملف، وتقوم علامة ate ببساطة بنقل العلامة إلى النهاية من الملف ولا يحد من مكان الكتابة.

لنقم بتطوير برنامج يقوم، باستخدام عملية sizeof()، بحساب خصائص أنواع البيانات الرئيسية في لغة C++ وكتابتها في ملف. تحديد:

  1. عدد البايتات المخصصة لنوع البيانات
  2. الحد الأقصى للقيمة التي يمكن لنوع بيانات معين تخزينها.

يجب أن تتم الكتابة إلى ملف بالتنسيق التالي:

/* نوع البيانات الحد الأقصى لقيمة bool = 1 255.00 char = 1 255.00 int قصير = 2 32767.00 int قصير غير موقع = 2 65535.00 int = 4 2147483647.00 int غير موقع = 4 4294967295.00 long int = 4 .00 unsigned long int = 4 4294967295.00 تعويم = 4 2147483647.00 تعويم طويل = 8 9223372036854775800.00 مزدوج = 8 9223372036854775800.00 */

تم تطوير مثل هذا البرنامج بالفعل في وقت سابق من هذا القسم، ولكن تم إخراج جميع المعلومات المتعلقة بأنواع البيانات إلى جهاز الإخراج القياسي، ونحن بحاجة إلى إعادة إنشاء البرنامج بحيث تتم كتابة المعلومات في ملف. للقيام بذلك، تحتاج إلى فتح الملف في وضع الكتابة، مع الاقتطاع الأولي لمعلومات الملف الحالية ( السطر 14). بمجرد إنشاء الملف وفتحه بنجاح (الأسطر 16 - 20)، بدلاً من عبارة cout، قم بإدخال in السطر 22نستخدم الكائن fout. وبالتالي، بدلاً من الشاشة، سيتم كتابة معلومات حول أنواع البيانات في ملف.

// write_file.cpp: يحدد نقطة الدخول لتطبيق وحدة التحكم. #تتضمن "stdafx.h" #تتضمن #يشمل // العمل مع الملفات #include // معالجات الإدخال والإخراج باستخدام مساحة الاسم std؛ int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // ربط الكائن بالملف، وفتح الملف في وضع الكتابة، وحذف جميع البيانات منه أولاً ofstream fout("data_types.txt" ", ios_base::out | ios_base::trunc); if (!fout.is_open()) // إذا لم يتم فتح الملف ( cout<< "Файл не может быть открыт или создан\n"; // напечатать соответствующее сообщение return 1; // выполнить выход из программы } fout << " data type " << "byte" << " " << " max value "<< endl // رؤوس الأعمدة <<"bool = " << sizeof(bool) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных bool*/ << (pow(2,sizeof(bool) * 8.0) - 1) << endl << "char = " << sizeof(char) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных char*/ << (pow(2,sizeof(char) * 8.0) - 1) << endl << "short int = " << sizeof(short int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных short int*/ << (pow(2,sizeof(short int) * 8.0 - 1) - 1) << endl << "unsigned short int = " << sizeof(unsigned short int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных unsigned short int*/ << (pow(2,sizeof(unsigned short int) * 8.0) - 1) << endl << "int = " << sizeof(int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных int*/ << (pow(2,sizeof(int) * 8.0 - 1) - 1) << endl << "unsigned int = " << sizeof(unsigned int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных unsigned int*/ << (pow(2,sizeof(unsigned int) * 8.0) - 1) << endl << "long int = " << sizeof(long int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных long int*/ << (pow(2,sizeof(long int) * 8.0 - 1) - 1) << endl << "unsigned long int = " << sizeof(unsigned long int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных undigned long int*/ << (pow(2,sizeof(unsigned long int) * 8.0) - 1) << endl << "float = " << sizeof(float) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных float*/ << (pow(2,sizeof(float) * 8.0 - 1) - 1) << endl << "long float = " << sizeof(long float) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных long float*/ << (pow(2,sizeof(long float) * 8.0 - 1) - 1) << endl << "double = " << sizeof(double) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных double*/ << (pow(2,sizeof(double) * 8.0 - 1) - 1) << endl; fout.close(); // программа больше не использует файл, поэтому его нужно закрыть cout << "Данные успешно записаны в файл data_types.txt\n"; system("pause"); return 0; }

من المستحيل عدم ملاحظة أن التغييرات في البرنامج ضئيلة، وكل ذلك بفضل حقيقة أن الإدخال/الإخراج القياسي وإدخال/إخراج الملفات يتم استخدامهما بنفس الطريقة تمامًا. وفي نهاية البرنامج الساعةالسطر 45لقد أغلقنا الملف بشكل صريح، على الرغم من أن ذلك ليس ضروريًا، ولكنه يعتبر ممارسة برمجية جيدة. تجدر الإشارة إلى أن جميع الوظائف والمعالجات المستخدمة لتنسيق الإدخال/الإخراج القياسي هي أيضًا ذات صلة بإدخال/إخراج الملف. لذلك، لم تحدث أية أخطاء عند البيان cout تم استبداله بكائن com.fout.

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

نصيتم استدعاء الملفات التي تتكون من أي أحرف. وهي منظمة في أسطر، ينتهي كل منها بـ " نهاية السطر". تتم الإشارة إلى نهاية الملف نفسه بالرمز " نهاية الملف". عند كتابة المعلومات في ملف نصي، والذي يمكن عرضه باستخدام أي محرر نصوص، يتم تحويل جميع البيانات إلى نوع حرف وتخزينها في شكل حرف.

في ثنائيفي الملفات، تتم قراءة المعلومات وكتابتها على شكل كتل ذات حجم معين، حيث يمكن تخزين البيانات من أي نوع وبنية.

للعمل مع الملفات، تسمى أنواع البيانات الخاصة تيارات.تدفق com.ifstreamيستخدم للعمل مع الملفات في وضع القراءة، و ofstreamفي وضع التسجيل. للعمل مع الملفات في وضع الكتابة والقراءة، يتم استخدام الدفق com.fstream.

في برامج C++، عند العمل مع الملفات النصية، تحتاج إلى تضمين المكتبات com.iostreamو com.fstream.

لكتابة البيانات في ملف نصي، يجب عليك:

  1. وصف متغير النوع ofstream.
  2. يفتح.
  3. إخراج المعلومات إلى ملف.
  4. تأكد من إغلاق الملف.

لقراءة البيانات من ملف نصي، يجب عليك:

  1. وصف متغير النوع com.ifstream.
  2. فتح الملف باستخدام الوظيفة يفتح.
  3. قراءة المعلومات من ملف؛ عند قراءة كل جزء من البيانات، من الضروري التحقق مما إذا تم الوصول إلى نهاية الملف.
  4. أغلق الملف.

كتابة المعلومات في ملف نصي

كما ذكرنا سابقًا، من أجل البدء في العمل مع ملف نصي، تحتاج إلى وصف متغير مثل ofstream. على سبيل المثال، مثل هذا:

أوفستريم F؛

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

ف.يفتح("ملف", وضع);

هنا ف- متغير موصوف بـ ofstream, ملف- الاسم الكامل للملف الموجود على القرص، وضع- طريقة العمل مع الملف الذي يتم فتحه. يرجى ملاحظة أنه عند تحديد اسم الملف الكامل، يجب عليك استخدام شرطة مائلة مزدوجة. للوصول، على سبيل المثال، إلى ملف حسابات.txt،الموجود في المجلد المواقع على القرص د، في البرنامج يجب عليك تحديد: د:\\المواقع\\ الحسابات.رسالة قصيرة.

يمكن فتح الملف بأحد الأوضاع التالية:

  • دائرة الرقابة الداخلية::في- فتح الملف في وضع قراءة البيانات؛ الوضع هو الوضع الافتراضي للمواضيع com.ifstream;
  • دائرة الرقابة الداخلية::خارج- فتح الملف في وضع تسجيل البيانات (في هذه الحالة، يتم إتلاف المعلومات حول الملف الموجود)؛ الوضع هو الوضع الافتراضي للمواضيع ofstream;
  • دائرة الرقابة الداخلية::التطبيق- فتح الملف في وضع كتابة البيانات إلى نهاية الملف؛
  • دائرة الرقابة الداخلية::أكلت- الانتقال إلى نهاية ملف مفتوح بالفعل؛
  • دائرة الرقابة الداخلية::ترونك- امسح الملف، ويحدث هذا أيضًا في وضع ios::out؛
  • ios::nocreate- لا تقم بعملية فتح الملف إذا لم يكن موجودا؛
  • ios::noreplace- لا تفتح ملف موجود.

قد تكون معلمة الوضع غائبة، وفي هذه الحالة يتم فتح الملف في الوضع الافتراضي لهذا الدفق.

بعد فتح الملف بنجاح (في أي وضع) في المتغير فسيتم تخزينها حقيقي، خلاف ذلك خطأ شنيع. سيسمح لك ذلك بالتحقق من صحة عملية فتح الملف.

افتح ملفًا (لنأخذ الملف كمثال د:\\المواقع\\ الحسابات.رسالة قصيرة) في وضع التسجيل، يمكنك القيام بأحد الإجراءات التالية:

بعد فتح الملف في وضع الكتابة، سيتم إنشاء ملف فارغ يمكنك كتابة المعلومات فيه.

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

بعد فتح ملف في وضع التسجيل، يمكنك الكتابة عليه بنفس طريقة الكتابة على الشاشة، فقط بدلاً من جهاز الإخراج القياسي coutيجب عليك تحديد اسم الملف المفتوح.

على سبيل المثال، الكتابة إلى دفق فعامل أ، سيبدو بيان الإخراج كما يلي:

ف<

للإخراج التسلسلي للدفق زالمتغيرات ب, ج, دسوف يصبح بيان الإخراج مثل هذا:

ز<

يتم إغلاق الدفق باستخدام عامل التشغيل:

F. Close();

على سبيل المثال، النظر في المشكلة التالية.

المشكلة 1

إنشاء ملف نصي د:\\ المواقع\\الحسابات .رسالة قصيرةوالكتابة فيه نأرقام حقيقية.

حل

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

#تشمل "stdafx.h"
#يشمل
#يشمل
#يشمل
باستخدام مساحة الاسم الأمراض المنقولة جنسيا؛
إنت الرئيسي ()
{

إنت ط، ن؛
مزدوج أ؛
// يصف دفقًا لكتابة البيانات إلى ملف
أوفستريم و؛
// فتح الملف في وضع الكتابة،
//ios::out يتم تعيين الوضع افتراضيًا
f.open("د: \\المواقع\\الحسابات.txt", ios::out );
// أدخل عدد الأعداد الحقيقية
cout<< «n=» ; cin >>ن;
// حلقة لإدخال الأرقام الحقيقية
// واكتبها في ملف
ل (ط = 0 ؛ ط< n; i++ )
{
cout<< «a=» ;
// أدخل رقما
سين >> أ;
و<< a<< «\ر «;
}
// إغلاق الدفق
f. Close();
نظام("وقفة");
العودة 0 ;
}

قراءة المعلومات من ملف نصي

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

بعد فتح ملف في وضع القراءة، يمكنك قراءة المعلومات منه بنفس الطريقة التي تقرأ بها من لوحة المفاتيح، فقط بدلاً من ذلك سينماتحتاج إلى تحديد اسم الدفق الذي سيتم قراءة البيانات منه.

على سبيل المثال، لقراءة البيانات من دفق فإلى متغير أ، سيبدو بيان الإدخال كما يلي:

و>>أ؛

يعتبر الرقمان في محرر النصوص منفصلين إذا كان هناك حرف واحد على الأقل بينهما: مسافة، علامة تبويب، نهاية السطر. من الجيد أن يعرف المبرمج مسبقًا عدد القيم المخزنة في الملف النصي وما هي القيم. ومع ذلك، غالبًا ما يكون نوع القيم المخزنة في الملف هو المعروف فقط، وقد يختلف عددها. لحل هذه المشكلة، تحتاج إلى قراءة القيم من الملف واحدة تلو الأخرى، وقبل كل قراءة، تحقق مما إذا تم الوصول إلى نهاية الملف. وسوف تساعد الوظيفة على القيام بذلك F.eof(). هنا ف- اسم الموضوع ترجع الدالة قيمة منطقية: حقيقيأو خطأ شنيع، اعتمادًا على ما إذا تم الوصول إلى نهاية الملف.

لذلك، يمكن كتابة حلقة لقراءة محتويات الملف بأكمله على النحو التالي:

لاستيعاب المادة بشكل أفضل، فكر في المشكلة.

المشكلة 2

يقوم الملف النصي D:\\game\\accounts.txt بتخزين الأرقام الحقيقية وعرضها على الشاشة وحساب أرقامها.

حل

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

#تشمل "stdafx.h"
#يشمل
#يشمل
#يشمل
#يشمل
باستخدام مساحة الاسم الأمراض المنقولة جنسيا؛
إنت الرئيسي ()
{
setlocale(LC_ALL, "RUS");
كثافة العمليات ن = 0 ;
تعويم أ؛
fstream F؛
// افتح الملف في وضع القراءة
F.فتح("د: \\المواقع\\الحسابات.txt") ;
// إذا تم فتح الملف بشكل صحيح، ثم
إذا (و)
{
// حلقة لقراءة القيم من الملف؛ سيتم مقاطعة تنفيذ الحلقة،
// عندما نصل إلى نهاية الملف، في هذه الحالة سيعود F.eof() إلى القيمة true.
بينما (!F.eof())
{
// قراءة القيمة التالية من الدفق F إلى المتغير a
ف >> أ؛
// إخراج قيمة المتغير أ إلى الشاشة
cout<< a<< «\ر «;
// زيادة عدد الأرقام المقروءة
ن++؛
}
// إغلاق الدفق
F. Close();
// الإدخال على الشاشة عدد الأرقام المقروءة
cout<< «n=» << n<< endl;
}
// إذا كان فتح الملف غير صحيح، ثم الإخراج
// رسائل حول عدم وجود مثل هذا الملف
آخر قطع<< "الملف غير موجود"<< endl;
نظام("وقفة");
العودة 0 ;
}

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

آخر تحديث: 31/10/2015

هناك فئتان مصممتان للعمل مع الدلائل في مساحة الاسم System.IO: Directory وDirectoryInfo.

فئة الدليل

توفر فئة الدليل عددًا من الطرق الثابتة لإدارة الدلائل. بعض هذه الأساليب:

    CreateDirectory(path): يقوم بإنشاء دليل على المسار المحدد

    حذف (المسار): يحذف الدليل الموجود في المسار المحدد

    موجود (المسار): يحدد ما إذا كان الدليل الموجود في المسار المحدد موجودًا أم لا. إذا كان موجودًا، فسيتم إرجاع صحيح، وإذا لم يكن موجودًا، فسيتم إرجاع خطأ

    GetDirectories(path): الحصول على قائمة الدلائل في مسار الدليل

    GetFiles(path): يحصل على قائمة بالملفات الموجودة في مسار الدليل

    نقل (sourceDirName، destDirName): ينقل الدليل

    GetParent(path): احصل على الدليل الأصلي

فئة معلومات الدليل

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

    إنشاء (): إنشاء دليل

    CreateSubdirectory(path): إنشاء دليل فرعي على المسار المحدد

    حذف (): يحذف الدليل

    الخاصية موجودة: تحدد ما إذا كان الدليل موجودًا أم لا

    GetDirectories (): الحصول على قائمة الدلائل

    GetFiles () : الحصول على قائمة الملفات

    MoveTo(destDirName): ينقل الدليل

    الخاصية الأصل: الحصول على الدليل الأصل

    خاصية الجذر: الحصول على الدليل الجذر

دعونا نلقي نظرة على أمثلة لاستخدام هذه الفئات

الحصول على قائمة الملفات والدلائل الفرعية

سلسلة dirName = "C:\\"; إذا (Directory.Exists(dirName)) ( Console.WriteLine("Subdirectories:"); string dirs = Directory.GetDirectories(dirName); foreach (سلسلة s في dirs) ( Console.WriteLine(s); ) Console.WriteLine( Console.WriteLine("Files:");

يرجى ملاحظة استخدام الخطوط المائلة في أسماء الملفات. إما أن نستخدم شرطة مائلة مزدوجة: "C:\\" أو شرطة مائلة واحدة، ولكن بعد ذلك نضع علامة @ أمام المسار بأكمله: @"C:\Program Files"

إنشاء دليل

مسار السلسلة = @"C:\SomeDir"; سلسلة فرعية = @"program\avalon"; DirectoryInfo dirInfo = new DirectoryInfo(path); إذا (!dirInfo.Exists) ( dirInfo.Create(); ) dirInfo.CreateSubdirectory(subpath);

أولاً، نتحقق مما إذا كان هذا الدليل موجودًا، لأنه إذا كان موجودًا، فلن يكون من الممكن إنشاؤه، وسيقوم التطبيق بإلقاء خطأ. ونتيجة لذلك، سوف نحصل على المسار التالي: "C:\SomeDir\program\avalon"

الحصول على معلومات الدليل

string dirName = "C:\\Program Files"; DirectoryInfo dirInfo = new DirectoryInfo(dirName); Console.WriteLine($"اسم الدليل: (dirInfo.Name)"); Console.WriteLine($"اسم الدليل الكامل: (dirInfo.FullName)"); Console.WriteLine($"وقت إنشاء الدليل: (dirInfo.CreationTime)"); Console.WriteLine($"الجذر: (dirInfo.Root)");

إزالة الدليل

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

String dirName = @"C:\SomeFolder"; حاول ( DirectoryInfo dirInfo = new DirectoryInfo(dirName); dirInfo.Delete(true); Console.WriteLine("تم حذف الدليل"); ) التقط (استثناء ex) ( Console.WriteLine(ex.Message); )

String dirName = @"C:\SomeFolder"; Directory.Delete(dirName, true);

نقل الدليل

string oldPath = @"C:\SomeFolder"; string newPath = @"C:\SomeDir"; DirectoryInfo dirInfo = new DirectoryInfo(oldPath); إذا (dirInfo.Exists && Directory.Exists(newPath) == false) ( dirInfo.MoveTo(newPath); )

عند النقل يجب أن نأخذ في الاعتبار أن الدليل الجديد الذي نريد نقل كافة محتويات الدليل القديم إليه يجب أن لا يكون موجودا.