كيفية قراءة الملف بأكمله ج. الإدخال من ملف والإخراج إلى ملف

19.09.2019

في السابق، عند إدخال البيانات وإخراجها، عملنا مع التدفقات القياسية - لوحة المفاتيح والشاشة. الآن دعونا نلقي نظرة على كيفية تنفيذ لغة C لاستلام البيانات من الملفات وكتابتها هناك. قبل أن تتمكن من تنفيذ هذه العمليات، يجب عليك فتح الملف والوصول إليه.

في لغة البرمجة C، يكون المؤشر إلى الملف من النوع FILE ويكون إعلانه كما يلي:
ملف *ملفي؛

من ناحية أخرى، تفتح الدالة fopen() ملفًا على العنوان المحدد كأول وسيط لها في وضع القراءة ("r")، أو وضع الكتابة ("w")، أو وضع الإلحاق ("a") وترجع مؤشرًا إليها إلى البرنامج. لذلك، تبدو عملية فتح الملف وربطه بالبرنامج كما يلي:
myfile = fopen("hello.txt", "r");

عند قراءة البيانات أو كتابتها في ملف، يتم الوصول إليها من خلال مؤشر الملف (في هذه الحالة، myfile).

إذا لسبب أو لآخر (لا يوجد ملف على العنوان المحدد، تم رفض الوصول إليه) لا يمكن للدالة fopen() فتح الملف، فإنها ترجع NULL. في البرامج الحقيقية، غالبًا ما يتعاملون مع خطأ فتح الملف في فرع if، ولكننا سنحذف هذا الأمر أكثر.

إعلان الدالة fopen() موجود في الملف الرأسي stdio.h، لذلك يجب تضمينه. أيضًا في stdio.h تم الإعلان عن نوع البنية FILE.

بعد الانتهاء من العمل مع الملف، من المعتاد إغلاقه لتحرير المخزن المؤقت من البيانات ولأسباب أخرى. وهذا مهم بشكل خاص إذا استمر البرنامج في العمل بعد العمل مع الملف. يتم قطع الاتصال بين الملف الخارجي والمؤشر إليه من البرنامج باستخدام الدالة fClose(). يتم تمرير مؤشر إلى الملف كمعلمة:
fClose(myfile);

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

القراءة من والكتابة إلى ملف نصي

فسكانف ()

الدالة fscanf() مشابهة في المعنى للدالة scanf()، ولكن على عكسها، فهي توفر مدخلات منسقة من ملف بدلاً من دفق الإدخال القياسي. تأخذ الدالة fscanf() معلمات: مؤشر الملف، وسلسلة التنسيق، وعناوين مناطق الذاكرة لكتابة البيانات:
fscanf(myfile, "%s%d", str, &a);

إرجاع عدد البيانات المقروءة بنجاح أو EOF. يتم حساب المسافات وأحرف السطر الجديد كمحددات للبيانات.

لنفترض أن لدينا ملفًا يحتوي على الوصف التالي للكائنات:

تفاح 10 23.4 موز 5 25.0 خبز 1 10.3

#يشمل main () ( FILE * file; struct food ( char name[ 20 ] ; الكمية غير الموقعة; Float Price; ) ; struct food shop[ 10 ; char i= 0 ; file = fopen ("fscanf.txt" , "r" ) ; while (fscanf (file, "%s%u%f" , shop[ i].name , & (shop[ i].qty ) , & (shop[ i].price ) != EOF) ( printf ( "%s %u %.2f \ن"، متجر[i].name، متجر[i].الكمية، متجر[i].السعر)؛ أنا++; ))

في هذه الحالة، يتم الإعلان عن بنية ومجموعة من الهياكل. يتوافق كل سطر من الملف مع عنصر واحد من المصفوفة؛ عنصر المصفوفة عبارة عن بنية تحتوي على سلسلة وحقلين رقميين. تقرأ الحلقة صفًا واحدًا لكل تكرار. عند مواجهة نهاية الملف، تقوم fscanf() بإرجاع EOF وتنتهي الحلقة.

فجيتس ()

تشبه الدالة fgets() الدالة gets() وتقوم بإدخال سطر تلو الآخر من الملف. مكالمة واحدة إلى fgets() ستقرأ سطرًا واحدًا. في هذه الحالة، لا يمكنك قراءة السطر بأكمله، بل جزء منه فقط من البداية. تبدو معلمات fgets() كما يلي:
fgets (character_array، number_of_characters_read، pointer_to_file)

على سبيل المثال:
فجيتس (شارع، 50، مايفيل)

سيتم قراءة استدعاء الدالة هذا من الملف المرتبط بمؤشر myfile سطرًا كاملاً من النص إذا كان طوله أقل من 50 حرفًا، بما في ذلك الحرف "\n"، الذي ستخزنه الدالة أيضًا في صفيف. سيكون العنصر الأخير (50) من المصفوفة str هو الحرف "\0" الذي تمت إضافته بواسطة fgets() . إذا كانت السلسلة أطول، فستقرأ الدالة 49 حرفًا وتكتب "\0" في النهاية. في هذه الحالة، لن يتم تضمين "\n" في سطر القراءة.

#يشمل #define N 80 main () ( FILE * file; char arr[ N] ; file = fopen ("fscanf.txt" , "r" ) ; while (fgets (arr, N, file) != NULL) printf (" %s" , arr) ; printf (" \ن") ; f Close(file); )

في هذا البرنامج، على عكس البرنامج السابق، تتم قراءة البيانات سطرًا تلو الآخر في المصفوفة arr. عند قراءة السطر التالي، يتم فقدان السطر السابق. تقوم الدالة fgets() بإرجاع NULL إذا لم تتمكن من قراءة السطر التالي.

getc() أو fgetc()

تتيح لك الدالة getc() أو fgetc() (كلاهما يعملان) الحصول على الحرف الفردي التالي من الملف.

بينما ((arr[ i] = fgetc (ملف) ) != EOF) ( if (arr[ i] == " \ن") (arr[i] = " \0 " ; طباعة("%s \ن"، آر) ؛ أنا = 0 ; ) آخر أنا ++؛ )آر[i] = " \0 " ; طباعة("%s \ن"، آر) ؛

يعرض رمز المثال بيانات من ملف على الشاشة.

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

تمامًا مثل الإدخال، يمكن أن يكون الإخراج إلى ملف مختلفًا.

  • الإخراج المنسق. وظيفة fprintf (file_index، format_string، المتغيرات).
  • إخراج ما بعد السطر. الدالة fputs(string, file_pointer) .
  • إخراج حرف تلو الآخر. الدالة fputc() أو putc(symbol, file_pointer) .

فيما يلي أمثلة التعليمات البرمجية التي تستخدم ثلاث طرق لإخراج البيانات إلى ملف.

كتابة الحقول ذات بنية واحدة في كل سطر من الملف:

ملف = fopen ("fprintf.txt"، "w" ) ؛ while (scanf ("%s%u%f" , shop[ i].name , & (shop[ i].qty ) , & (shop[ i].price ) ) != EOF) ( fprintf (ملف، " %s %u %.2f \ن"، متجر[i].name، متجر[i].الكمية، متجر[i].السعر)؛ أنا++; )

إخراج سطرًا تلو الآخر إلى ملف (fputs()، على عكس puts() نفسها، لا تضع "\n" في نهاية السطر):

بينما (يحصل على (arr) ! = NULL) ( fputs (arr، file)؛ fputs (" \ن"، ملف)؛

)

مثال على إخراج حرف تلو الآخر:

while ((i = getchar () ) != EOF) putc (i, file) ;

القراءة من والكتابة إلى ملف ثنائي

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

عند فتح ملف للوصول الثنائي، فإن المعلمة الثانية لـ fopen() هي السلسلة النصية "rb" أو "wb".

موضوع العمل مع الملفات الثنائية معقد للغاية ويتطلب درسًا منفصلاً لدراسته. هنا سيتم ملاحظة فقط ميزات وظائف القراءة والكتابة للملف، والتي تعتبر بمثابة دفق بايت.

  1. تأخذ الدالتان fread() وfwrite() كمعلمات:
  2. عنوان منطقة الذاكرة حيث تتم كتابة البيانات أو القراءة منها،
  3. حجم واحد نظرا لأي نوع،
  4. كمية البيانات المقروءة بالحجم المحدد،

فهرس الملف.

تقوم هذه الوظائف بإرجاع عدد البيانات المقروءة أو المكتوبة بنجاح. أولئك. يمكنك "طلب" قراءة 50 عنصرًا من عناصر البيانات، ولكنك تتلقى 10 عناصر فقط. ولن يكون هناك أي خطأ.

#يشمل مثال على استخدام الدالتين fread() و fwrite(): #يشمل \0 " main () ( FILE * file; char shelf1[ 50 ], shelf2[ 100 ] ; int n, m; file = fopen ("shelf1.txt" , "rb" ) ; n= fread (shelf1, sizeof (char ) , 50 ، ملف) ؛ fclose (ملف) ؛ file = fopen ("shelf2.txt"، "rb" ) ؛ m= fread (shelf2، sizeof (char ) ، 50 ، file) ؛ \ن"; الرف2[م+1] = " \0 " ; ملف = fopen ("shop.txt" , "wb" ) ؛ fwrite (strcat (shelf2, shelf1) , sizeof (char ) , n+ m, file) ؛ f Close(file); )

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

حل المشاكل

  1. اكتب برنامجًا يطلب من المستخدم اسم (عنوان) ملف نصي، ثم يفتحه ويحصي عدد الأحرف والسطور الموجودة فيه.
  2. كتابة برنامج يكتب إلى ملف البيانات الواردة من ملف آخر ويتم تعديلها بطريقة ما قبل كتابتها. يجب أن يتناسب كل سطر من البيانات التي تم الحصول عليها من الملف مع البنية.

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

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

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

نظام الملفاتيسمى الجزء الوظيفي من نظام التشغيل الذي ينفذ العمليات على الملفات. من أمثلة أنظمة الملفات 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"، وسيطات);

سيناقش هذا القسم طريقتين للعمل مع الملفات وفئة MFC CFileDialog القياسية.


1. العمل مع الملفات في لغة C (يعمل في لغة C++ أيضًا).


    #يشمل
    #يشمل

الفراغ الرئيسي (باطل)
{
ملف * ملف؛
شار* file_name = "file.txt";
شارload_string = "لا شيء";

File = fopen(file_name, "w");

Fputs("سلسلة"، ملف)؛

File = fopen(file_name, "r");
إذا (ملف! = 0)
{
fgets(load_string, 50 , file);
كوت)
آخر
{
كوت)
f Close(file);
) أوصاف وظائف العمل مع الملفات موجودة في المكتبة stdio.h
تحتاج أولاً إلى إنشاء مؤشر لمتغير من النوع FILE ( ملف * ملف؛).
يتم فتح الملف عن طريق استدعاء الدالة fopen ( file = fopen(file_name, "w");)
المعلمة الأولى لهذه الوظيفة هي اسم الملف، والثانية تحدد الوضع الذي يجب فتح الملف فيه. "ث"- مفتوح للتسجيل، "ص"- مفتوح للقراءة، "أ"- إضافة الملفات (هذه هي الأوضاع الأكثر استخدامًا، على الرغم من وجود أوضاع أخرى). تتم كتابة وقراءة البيانات من الملف من خلال الوظائف التالية: fputc، fputs، fgetc، fgets، fprintf، fscanf(للاطلاع على وصف هذه الوظائف، انظر stdio.h).
يتم إغلاق الملف عن طريق استدعاء الدالة fClose ( f Close(file);).

العمل مع الملفات باستخدام MFC (فئات CFile، CStdioFile، ...) وفئة MFC القياسية CFileDialog.


تتضمن مكتبة MFC عدة فئات للعمل مع الملفات. الفئات التي تمت مناقشتها أدناه ترث من الفئة الأساسية

ملف C.

فئة CF

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

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

يفتح.

فتح وإنشاء الملفات

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

Virtual BOOL Open(LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError=NULL);

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

تحدد المعلمة الثانية، nOpenFlags، الإجراء الذي تنفذه الطريقة Open على الملف، بالإضافة إلى سمات الملف. فيما يلي بعض القيم المحتملة للمعلمة nOpenFlags:

  • CFile::modeCreate - يقوم بإنشاء ملف جديد. في حالة وجود الملف المحدد، يتم مسح محتوياته وضبط طول الملف على صفر.
  • CFile::modeNoTruncate - هذا الملف مخصص للاستخدام مع ملف CFile::modeCreate. إذا تم إنشاء ملف موجود، فلن يتم حذف محتوياته.

  • CFile::modeRea د - يتم فتح الملف للقراءة فقط.
  • CFile::modeReadWrite - يتم فتح الملف للكتابة والقراءة.
  • CFile::modeWrite - الملف مفتوح للكتابة فقط.
  • CFile::typeText - تستخدمه الفئات المشتقة من فئة CFile، مثل CStdioFile، للعمل مع الملفات في الوضع النصي. يقوم وضع النص بتحويل مجموعة حرف إرجاع السطر وحرف تغذية السطر.
  • CFile::Binary - يستخدم بواسطة الفئات المشتقة من فئة CFile، مثل CStdioFile، للعمل مع الملفات في الوضع الثنائي.
  • خطأ المعلمة الاختيارية، وهو مؤشر إلى كائن فئة CFileException، يتم استخدامه فقط إذا كان إجراء عملية على الملف سيؤدي إلى حدوث خطأ. في هذه الحالة، سيتم كتابة معلومات إضافية إلى الكائن المشار إليه بواسطة خطأ.

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

    فتح معرف الملف

    تتضمن فئة CFile عنصر بيانات m_hFile من النوع UINT. يقوم بتخزين معرف الملف المفتوح. إذا تم بالفعل إنشاء كائن من فئة CFile، ولكن لم يتم فتح الملف بعد، فسيتم كتابة الثابت hFileNull في المتغير m_hFile.

    عادةً لا يتم استخدام معرف الملف المفتوح مباشرة. طرق الصف ملف Cيسمح لك بإجراء أي عملية تقريبًا مع الملفات ولا يتطلب منك تحديد معرف الملف. نظرًا لأن m_hFile هو عنصر فئة، فإن تنفيذ أساليبه يتمتع دائمًا بإمكانية الوصول إليه مجانًا.

    إغلاق الملفات

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

    قراءة وكتابة الملفات

    هناك عدة طرق فئة للوصول إلى الملفات. ملف C: القراءة، القراءة الضخمة، الكتابة، الكتابة الضخمة، التدفق. طُرق قراءة وقراءة ضخمةمصممة لقراءة البيانات من ملف مفتوح مسبقًا. في أنظمة التشغيل 32 بت، يمكن لكلتا الطريقتين قراءة أكثر من 65535 بايت من الملف في وقت واحد. تعتبر مواصفات ReadHuge قديمة ويتم الاحتفاظ بها فقط للتوافق مع أنظمة التشغيل 16 بت.

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

    تهدف أساليب Write وWriteHuge إلى الكتابة إلى ملف. في أنظمة التشغيل 32 بت، يمكن لكلا الطريقتين كتابة أكثر من 65535 بايت إلى ملف في وقت واحد. تقوم الأساليب بكتابة البايتات من المخزن المؤقت lpBuf إلى الملف المفتوح nCount. في حالة حدوث خطأ في الكتابة، مثل امتلاء القرص، تقوم الأساليب باستدعاء معالجة الاستثناءات.

    طريقة فلوش

    عند استخدام أسلوب Write أو WriteHuge لكتابة البيانات إلى القرص، فقد تظل في مخزن مؤقت مؤقت لبعض الوقت. للتأكد من إجراء التغييرات اللازمة على الملف الموجود على القرص، تحتاج إلى استخدام طريقة Flush.

    عمليات الملف

    يتضمن الفصل أساليب تسمح لك بتنفيذ عمليات مختلفة على الملفات، مثل النسخ وإعادة التسمية والحذف وتغيير السمات.

    لتغيير اسم الملف، تتضمن فئة CFile أسلوبًا ثابتًا إعادة تسميةالذي ينفذ وظائف هذا الأمر. لا يمكن استخدام الأسلوب لإعادة تسمية الدلائل. في حالة حدوث خطأ، تثير الطريقة استثناءً.

    يتم تضمين طريقة ثابتة في فئة CFile لحذف الملفات يزيل، والذي يسمح لك بحذف الملف المحدد. هذه الطريقة لا تسمح لك بحذف الدلائل. إذا تعذر حذف الملف، فستطرح الطريقة استثناءً.

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

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

    نسخة ثابتة من الطريقة احصل على الحالةيسمح لك بتحديد خصائص الملف غير المرتبط بكائن من فئة CFile. لاستخدام هذه الطريقة، ليس من الضروري فتح الملف أولاً.

    الحظر

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

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

    التمركز

    لتحريك مؤشر موضع الملف الحالي إلى موضع جديد، يمكنك استخدام إحدى طرق الفئة التالية ملف C - تسعى، SeekToBegin، SeekToEnd.الى الصف ملف Cيتضمن أيضًا طرقًا تتيح لك ضبط طول الملف وتغييره، -احصل على الطول، سيتلينغث.

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

    لتحريك مؤشر موضع الملف الحالي إلى أي مكان، يمكنك استخدام الطريقة العامة

    يطلب. يسمح لك بتحريك المؤشر لعدد معين من البايتات بالنسبة إلى موضع البداية أو النهاية أو موضع المؤشر الحالي.

    لتحريك المؤشر إلى بداية الملف أو نهايته، يكون من الأنسب استخدام أساليب خاصة. طريقة

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

    ولكن لتحديد طول الملف المفتوح، ليس من الضروري تحريك المؤشر الخاص به. يمكنك استخدام الطريقة

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

    يمكن تحديد موضع مؤشر الملف الحالي باستخدام الطريقة

    GetPosition. عاد عن طريق الطريقةGetPositionتحدد القيمة 32 بت إزاحة المؤشر من بداية الملف.

    فتح خصائص الملف

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

    إذا كنت تحتاج فقط إلى تحديد اسم وامتداد الملف المفتوح، فيمكنك استخدام هذه الطريقة GetFileName. تقوم بإرجاع كائن CString يحتوي على اسم الملف. في الحالة عندما تحتاج إلى معرفة اسم الملف المفتوح بدون امتداد فقط، استخدم الطريقةGetFileTitle.

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

    فئة ج

    MemFile

    تتضمن مكتبة MFC الفئة

    CMemFile، موروثة من الطبقة الأساسيةملف C. فصل CMemFileيمثل ملفًا موجودًا في ذاكرة الوصول العشوائي (RAM). مع كائنات الطبقةCMemFileكما هو الحال مع كائنات الفئةملف C. الفرق هو أن الملف مرتبط بالكائنCMemFile، لا يوجد على القرص، ولكن في ذاكرة الوصول العشوائي للكمبيوتر. ونتيجة لهذا، تكون العمليات مع مثل هذا الملف أسرع بكثير من الملفات العادية.

    العمل مع كائنات الفئة

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

    يوجد منشئان مختلفان لإنشاء كائنات من فئة CMemFile. يحتوي مُنشئ CMemFile الأول على معلمة اختيارية واحدة فقط nGrowBytes:

    CMemFile(UINT nGrowBytes=1024);

    يقوم هذا المُنشئ بإنشاء ملف فارغ في ذاكرة الوصول العشوائي (RAM). بمجرد إنشائه، يتم فتح الملف تلقائيًا (لا داعي لاستدعاء الأسلوب Ope

    ن).

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

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

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

    CMemFile(BYTE* lpBuffer, UINT nBufferSize, UINT nGrowBytes=0);

    تحدد المعلمة lpBuffer المخزن المؤقت الذي سيتم استخدامه للملف. يتم تحديد حجم المخزن المؤقت بواسطة المعلمة nBufferSize.

    يتم استخدام المعلمة nGrowBytes الاختيارية بشكل أكثر شمولاً من مُنشئ الفئة الأولى. إذا كان nGrowBytes يحتوي على صفر، فسيحتوي الملف الذي تم إنشاؤه على البيانات من lpBuffer. سيكون طول هذا الملف مساوياً لـ nBufferSize.

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

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

    تجدر الإشارة إلى أنه لإدارة المخزن المؤقت للملف، يجب استخدام الفصل

    CMemFileيستدعي الوظائف القياسيةمالوك، إعادة تخصيصو حر. لذلك، حتى لا يتم كسر آلية إدارة الذاكرة، يجب إنشاء المخزن المؤقت lpBuffer بواسطة الوظائفmallocأو calloc.

    فئة CStdioFile

    يجب على أولئك الذين اعتادوا على استخدام وظائف الإدخال / الإخراج المتدفقة من مكتبة C و C++ القياسية الانتباه إلى الفصل

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

    منشئ من الدرجة الثانية

    CStdioFileيمكن استدعاؤه إذا كان الملف مفتوحًا بالفعل وتحتاج إلى إنشاء كائن جديد من فئة CStdioFile وربط الملف المفتوح به. يمكن استخدام هذا المنشئ إذا تم فتح الملف بوظيفة قياسيةcom.fopen. يجب أن تحتوي معلمة الطريقة على مؤشر للملف الذي تم الحصول عليه عن طريق استدعاء الوظيفة القياسيةcom.fopen.

    يمكن استخدام المنشئ الثالث إذا كنت بحاجة إلى إنشاء كائن فئة

    CStdioFile، افتح ملفًا جديدًا واربطه بالكائن الذي تم إنشاؤه حديثًا.

    للقراءة والكتابة إلى ملف نصي، تتضمن فئة CStdioFile طريقتين جديدتين:

    قراءة سلسلةو سلسلة الكتابة. تسمح لك الطريقة الأولى بقراءة سلسلة من الأحرف من ملف، وتسمح لك الطريقة الثانية بكتابتها.

    أمثلة على الكتابة والقراءة من ملف

    فيما يلي أجزاء التعليمات البرمجية التي توضح استخدام لوحات حوار تحديد الملف القياسية وإجراءات القراءة والكتابة في الملف.

    فتح ملف والقراءة منه

    CString m_Text; …… // إنشاء لوحة اختيار ملف قياسي مفتوحة CFileDialog DlgOpen(TRUE,(LPCSTR)"txt",NULL, OFN_HIDEREADONLY,(LPCSTR)" Text Files (*.txt) |*.txt||"); // عرض لوحة اختيار الملف القياسي المفتوحةإذا (DlgOpen.DoModal()==IDOK) ( // أنشئ كائنًا وافتح الملف للقراءة CStdioFile File(DlgOpen.GetPathName(),CFile::modeRead|CFile::typeBinary); // قراءة السلاسل من الملف CString& ref=m_Text; File.ReadString(المرجع ); // تم تمرير مرجع إلى سلسلةم_النص)

    الفتح والكتابة من ملف

    CString m_Text; …… // إنشاء لوحة اختيار ملف SaveAs القياسية CFileDialog DlgSaveAs(FALSE,(LPCSTR)"txt",NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, (LPCSTR)" Text Files (*.txt) |*.txt||"); // عرض لوحة اختيار ملف SaveAs القياسيةإذا (DlgSaveAs.DoModal()==IDOK) ( // أنشئ كائنًا وافتح ملفًا للكتابة CStdioFile File(DlgSaveAs.GetPathName(), CFile::modeCreate|CFile::modeWrite|CFile::typeBinary); // الكتابة إلى ملف سلسلة File.WriteString((LPCTSTR)m_Text); )
      يحتوي على رمز العمل الخاص بالبرنامج، المصمم للبساطة كتطبيق وحدة التحكم ضمن MFC. لكي يعمل البرنامج لا تنسى القيام بما يلي:

      قم بتشغيل البرنامج - إنشاء / إعادة بناء الكل (ستكون هناك أخطاء)، حدد إنشاء / تعيين التكوين النشط - تحقيق Win 32، حدد عنصر القائمة "المشروع"، ثم "الإعدادات..."، علامة التبويب "C/C++"، الفئة - إنشاء التعليمات البرمجية وفي العنصر "استخدام مكتبة وقت التشغيل"، حدد "متعدد مؤشرات الترابط". بعد ذلك، قم بإجراء Build/Rebuild مرة أخرى وسيعمل البرنامج.

    - المقارنة لتحديد المساواة أو عدم المساواة.

    الغرض العملي من التعداد هو تعريف مجموعة من الثوابت الرمزية المميزة من نوع عدد صحيح.

    مثال على استخدام المتغيرات المذكورة:

    mo=1, tu, we, th, fr, sa, su ) أيام;

    يضع("أدخل يوم الأسبوع (من 1 إلى 7) :"); scanf("%d", &t_day);

    w_day = su; ابدأ = مو؛

    النهاية = w_day -t_day;

    printf("\nالاثنين هو %d يوم في الأسبوع، \nالآن هو %d يوم.\n\

    حتى نهاية الأسبوع %d يوم (أيام). "، البداية، t_day، النهاية)؛

    نتيجة البرنامج: أدخل يوم الأسبوع (من 1 إلى 7): 2

    الاثنين هو اليوم الأول من الأسبوع، والآن هو اليوم الثاني. هناك 5 أيام (أيام) حتى نهاية الأسبوع.

    18. الملفات بلغة C

    الملف عبارة عن مجموعة من البيانات الموجودة على وسائط خارجية ويتم اعتبارها وحدة واحدة أثناء المعالجة. تحتوي الملفات على بيانات مخصصة للتخزين على المدى الطويل.

    هناك نوعان من الملفات: نصية وثنائية. الملفات النصية عبارة عن سلسلة من أحرف ASCII ويمكن عرضها وتحريرها باستخدام أي محرر نصوص.

    الملفات الثنائية (الثنائية) هي سلسلة من البيانات، يتم تحديد بنيتها بواسطة البرنامج.

    تحتوي لغة C على مجموعة كبيرة من الوظائف للعمل مع الملفات، معظمها موجود في مكتبات stdio.h وio.h.

    18.1. فتح ملف

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

    المؤشر إلى الملف، أي. إلى منطقة الذاكرة التي تحتوي على كافة المعلومات الضرورية حول الملف. تنسيق الإعلان عن المؤشر إلى الملف هو كما يلي:

    ملف * مؤشر للملف؛

    FILE - معرف نوع البنية الموضح في المكتبة القياسية

    stdio.h وتحتوي على المعلومات التالية:

    نوع البنية(

    - عدد البايتات غير المقروءة المتبقية في المخزن المؤقت؛

    حجم المخزن المؤقت المعتاد هو 512 بايت؛ بمجرد المستوى = 0

    تتم قراءة كتلة البيانات التالية في المخزن المؤقت من الملف؛

    - علامة حالة الملف - القراءة والكتابة والإلحاق؛

    - واصف الملف، أي رقم يحدد رقمه

    عقد حرف غير موقعة؛

    - حرف غير منقول، أي. ungetc-character;

    - حجم المخزن المؤقت الوسيط الداخلي؛

    المخزن المؤقت شار غير الموقعة؛

    – قيمة المؤشر للوصول داخل المخزن المؤقت، أي

    يحدد بداية المخزن المؤقت، بداية السطر، أو القيمة الحالية

    قيمة المؤشر داخل المخزن المؤقت حسب الوضع

    التخزين المؤقت أماه؛

    غير موقعة شار *curp؛

    – القيمة الحالية للمؤشر للوصول داخل

    فيرا، أي. يحدد الموضع الحالي في المخزن المؤقت للتبادل

    مع البرنامج؛

    غير موقعة؛

    - إشارة الملف المؤقت؛

    - علامة عند العمل مع ملف؛

    ) ملف؛

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

    FILE* fopen(char* file_name, char* mode);

    فهو يأخذ تمثيلاً خارجيًا - الاسم الفعلي للملف الموجود على وسيط (قرص مرن، محرك أقراص ثابتة) ويطابقه باسم منطقي.

    الاسم المادي، أي. يتم تحديد اسم الملف والمسار إليه بواسطة المعلمة الأولى

    – سطر، على سبيل المثال، “a:Mas_dat.dat” – ملف اسمه Mas_dat.dat موجود على قرص مرن، “d:\\work\\Sved.txt” – ملف اسمه Sved.txt موجود على القرص الصلب القيادة في دليل العمل .

    انتباه! تتم كتابة الشرطة المائلة العكسية (\)، كحرف خاص، مرتين في السطر.

    عند الفتح الناجح، تقوم الدالة fopen بإرجاع مؤشر إلى الملف (يشار إليه فيما بعد بمؤشر الملف). عند حدوث خطأ، يتم إرجاع NULL. يحدث هذا الموقف عادةً عندما يتم تحديد المسار إلى الملف الذي سيتم فتحه بشكل غير صحيح. على سبيل المثال، إذا حددت في فصل العرض بجامعتنا مسارًا محظورًا للكتابة (عادةً ما يكون d:\work\ مسموحًا به).

    المعلمة الثانية عبارة عن سطر يحدد وضع الوصول إلى الملف:

    ث – الملف مفتوح للكتابة؛ إذا لم يكن هناك ملف بالاسم المحدد، فسيتم إنشاؤه؛ إذا كان هذا الملف موجودا، فسيتم إتلاف المعلومات السابقة قبل فتحه؛

    r - يفتح الملف للقراءة فقط؛ إذا لم يكن هناك مثل هذا الملف، يحدث خطأ؛

    أ – يتم فتح الملف لإضافة معلومات جديدة إلى النهاية؛

    r+ – الملف مفتوح لتحرير البيانات – من الممكن كتابة وقراءة المعلومات؛

    w+ – نفس الشيء بالنسبة لـ r+;

    a+ - كما هو الحال بالنسبة لـ a، يمكن إجراء الكتابة فقط في أي مكان في الملف؛ قراءة الملفات متاحة أيضًا؛

    t - يتم فتح الملف في الوضع النصي؛ ب - يتم فتح الملف في الوضع الثنائي.

    يختلف وضع النص عن الوضع الثنائي حيث أنه عند فتح ملف كنص، يتم استبدال زوج الأحرف "تغذية السطر" و"سطر الإرجاع" بحرف واحد: "تغذية السطر" لجميع وظائف كتابة البيانات إلى الملف وبالنسبة لجميع وظائف الإخراج، تم الآن استبدال حرف "تغذية السطر" بحرفين: "تغذية السطر" و"سطر الإرجاع".

    افتراضيًا، يتم فتح الملف في الوضع النصي. مثال: ملف *f؛ - تم الإعلان عن مؤشر للملف f؛

    f = fopen("d:\\work\\Dat_sp.cpp", "w"); - يتم فتح ملف بالاسم المنطقي f، والذي له الاسم الفعلي Dat_sp.cpp، الموجود على محرك الأقراص d، في دليل العمل، للكتابة؛ أو باختصار أكثر

    FILE *f = fopen("d:\\work\\Dat_sp.cpp", "w");

    18.2. إغلاق ملف

    بعد العمل مع ملف، يجب إغلاق الوصول إليه. يتم ذلك عن طريق الدالة int fclose (مؤشر الملف). على سبيل المثال، من المثال السابق يتم إغلاق الملف بهذا الشكل: f Close (f)؛

    لإغلاق ملفات متعددة، يتم تقديم وظيفة تم تعريفها على النحو التالي: void f Closeall (void)؛

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

    FILE* freopen (char*file_name, char *mode, FILE *file_pointer);

    تقوم هذه الوظيفة أولاً بإغلاق الملف المعلن file_pointer(كما تفعل الدالة fopen)، ثم يفتح الملف باسم الملف والأذونات "الوضع".

    تتمتع لغة C بالقدرة على العمل مع الملفات المؤقتة المطلوبة فقط أثناء تشغيل البرنامج. في هذه الحالة يتم استخدام الدالة

    ملف* tmpfile(باطل);

    الذي يقوم بإنشاء ملف مؤقت على القرص بحقوق الوصول "w+b" بعد اكتمال البرنامج أو بعد إغلاق الملف المؤقت، يتم حذفه تلقائيًا.

    18.3. الكتابة - قراءة المعلومات

    يمكن تقسيم جميع الإجراءات الخاصة بقراءة البيانات وكتابتها إلى ملف إلى ثلاث مجموعات: عمليات الإدخال والإخراج لكل حرف؛ عمليات الإدخال/الإخراج سطرًا تلو الآخر؛ منع عمليات الإدخال/الإخراج.

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

    الإدخال/الإخراج لكل حرف على حدة

    في وظائف الإدخال/الإخراج لكل حرف على حدة، يتم تلقي حرف واحد من ملف أو يتم إرسال حرف واحد إلى ملف:

    صف الإدخال/الإخراج

    يتم نقل وظائف الإدخال/الإخراج من ملف أو إلى

    كتلة الإدخال/الإخراج

    تعمل وظائف الإدخال/الإخراج على الكتل بأكملها

    معلومة:

    كثافة العمليات (void*p, intsize,

    - يقرأ n كتل بحجم بايت لكل منها من الملف

    كثافة العمليات ن، ملف * و)

    la f إلى منطقة الذاكرة بالمؤشر p (مطلوب

    int fwrite (void*p, intsize,

    تخصيص الذاكرة مسبقًا للكتلة المراد قراءتها)؛

    - يكتب n كتل بحجم بايت لكل منها

    كثافة العمليات ن، ملف * و)

    منطقة الذاكرة مع المؤشر p للملف f.

    يتم إنتاج الإدخال/الإخراج المنسق بواسطة الوظائف.

    العمل مع الملفات النصية في C++.

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

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

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

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

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

    بغرض اكتبالبيانات إلى ملف نصي، فأنت بحاجة إلى:

      وصف متغير من نوع الدفق.

      إخراج المعلومات إلى ملف.

      تأكد من إغلاق الملف.

    ل قراءةالبيانات من ملف نصي، تحتاج إلى:

      وصف متغير من النوع ifstream.

      افتح ملفًا باستخدام الوظيفة المفتوحة.

      أغلق الملف.

    سِجِلّالمعلومات إلى ملف نصي

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

      سيتم إنشاء متغير F لكتابة المعلومات إلى الملف.

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

    F.open("ملف"، الوضع);

    هنا F هو متغير يوصف بأنه ofstream،

    ملف - الاسم الكامل للملف الموجود على القرص،

    الوضع - وضع العمل مع الملف المفتوح.

    يرجى ملاحظة أنه عند تحديد اسم الملف الكامل، يجب عليك استخدام شرطة مائلة مزدوجة. على سبيل المثال، يجب كتابة الاسم الكامل للملف noobs.txt، الموجود في مجلد اللعبة على محرك الأقراص D:، على النحو التالي:

    D:\\game\\noobs.txt.

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

    ios::in - فتح الملف في وضع قراءة البيانات، هذا الوضع هو الوضع الافتراضي لتدفقات ifstream؛

    ios::out - فتح ملف في وضع كتابة البيانات (في هذه الحالة، يتم إتلاف المعلومات حول الملف الموجود)، هذا الوضع هو الوضع الافتراضي للتدفقات؛

    ios::app - افتح الملف في وضع كتابة البيانات حتى نهاية الملف؛

    ios::ate - الانتقال إلى نهاية الملف المفتوح بالفعل؛

    ios::trunc - امسح الملف، ويحدث هذا أيضًا في وضع ios::out؛

    ios::nocreate - لا تفتح ملفًا إذا لم يكن موجودًا؛

    ios::noreplace - لا تفتح ملفًا موجودًا.

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

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

    يمكنك فتح ملف (لنأخذ الملف D:\\game\\noobs.txt كمثال) في وضع التسجيل بإحدى الطرق التالية:

    // أولاً طريق

    أوفستريم F؛

    F.open("D:\\game\\noobs.txt", ios::out);

    // الطريقة الثانية، وضع ios::out هو الوضع الافتراضي

    // ل تدفقofstream

    أوفستريم F؛

    // تجمع الطريقة الثالثة بين وصف المتغير ونوع الدفق

    // وفتح الملف في عبارة واحدة

    ofstream F("D:\\game\\noobs.txt", ios::out);

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

    إذا كنت تريد فتح ملف موجود في وضع الكتابة أولاً، فيجب عليك استخدام ios::app كوضع.

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

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

    بالنسبة للإخراج المتسلسل لتدفق G للمتغيرات b، c، d، سيصبح عامل الإخراج كما يلي:

    ز<

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

    مثال:

    قم بإنشاء ملف نصي D:\\game\\noobs.txt واكتب فيه n أرقام حقيقية.

    #تشمل "stdafx.h"

    #يشمل

    #يشمل

    #يشمل

    استخدام اسم للمحطة؛

    انت مين()

    setlocale(LC_ALL, "RUS");

    إنت ط، ن؛

    مزدوج أ؛

    // يصف دفقًا لكتابة البيانات إلى ملف

    ofstream F;

    // فتح الملف في وضع الكتابة،

    //وضعدائرة الرقابة الداخلية:: خارجمثبتة بشكل افتراضي

    f.open("D:\\game\\noobs.txt", ios::out);

    // أدخل عدد الأعداد الحقيقية

    cout<<" ن="; سينما>> ن;

    // حلقة لإدخال الأرقام الحقيقية

    // واكتبها في ملف

    ل (ط = 0؛ ط

    cout<<"a=";

    //أدخل رقما

    سين>>أ;

    F<

    // إغلاق الدفق

    f. Close();

    نظام("وقفة");

    العودة 0؛

    _______________________________________________________________

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

    F.open("D:\\game\\noobs.txt", ios::in);

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

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

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

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

    // تنظيم لقراءة القيم من ملف، التنفيذ

    // سوف تنقطع الحلقة عندما نصل إلى نهاية الملف،

    // في هذه الحالة سيُرجع F.eof() صحيحًا

    بينما (!F.eof())

    مثال:

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

    #تشمل "stdafx.h"

    #يشمل

    #يشمل

    #يشمل

    #يشمل

    استخدام اسم للمحطة؛

    انت مين()

    setlocale(LC_ALL, "RUS");

    كثافة العمليات ن = 0؛

    تعويم أ؛

    fstream F ؛

    // افتح الملف في وضع القراءة

    F.open("D:\\game\\noobs.txt");

    // إذا تم فتح الملف بشكل صحيح، ثم

    // حلقة لقراءة القيم من الملف؛ سيتم مقاطعة تنفيذ الحلقة،

    // عندما نصل إلى نهاية الملف، في هذه الحالة سيعود F.eof() إلى القيمة true.

    بينما (!F.eof())

    // قراءة القيمة التالية من الدفق F إلى المتغير a

    و>>أ؛

    // إخراج قيمة المتغير أ إلى الشاشة

    cout<

    // زيادة عدد الأرقام المقروءة

    // إغلاق الدفق

    F. Close();

    // الإدخال على الشاشة عدد الأرقام المقروءة

    cout<<"n="<

    // إذا كان فتح الملف غير صحيح، ثم الإخراج

    // رسائل حول عدم وجود مثل هذا الملف

    آخر قطع<<" Файл не существует"<

    نظام("وقفة");

    العودة 0؛

    سي ++. معالجة الملفات الثنائية

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

    بغرض اكتبالبيانات إلى ملف ثنائي، تحتاج إلى:

      وصف متغير ملف من النوع FAIL * باستخدام عامل التشغيل FILE *filename؛ هنا اسم الملف هو اسم المتغير حيث سيتم تخزين المؤشر إلى الملف.

      كتابة المعلومات إلى ملف باستخدام الدالة fwrite

    بغرض يعتبر b من ملف ثنائي، يجب عليك:

      وصف متغير من النوع FILE *

      افتح ملفًا باستخدام الدالة fopen

      أغلق ملفًا باستخدام الدالة fclose

    الوظائف الأساسية المطلوبة للعمل مع الملفات الثنائية.

    ل الاكتشافاتالملف مخصص للوظيفة fopen.

    FILE *fopen(const *اسم الملف، const char *mode)

    هنا اسم الملف عبارة عن سلسلة تخزن الاسم الكامل للملف الذي يتم فتحه، والوضع عبارة عن سلسلة تحدد وضع العمل مع الملف؛ القيم التالية ممكنة:

    "rb" - فتح الملف الثنائي في وضع القراءة؛

    "wb" - إنشاء ملف ثنائي للتسجيل؛ إذا كان موجودا، يتم مسح محتوياته؛

    "ab" - إنشاء أو فتح ملف ثنائي لإلحاقه بنهاية الملف؛

    "rb+" - فتح ملف ثنائي موجود في وضع القراءة والكتابة؛

    "wb+" - فتح الملف الثنائي في وضع القراءة والكتابة، ويتم مسح الملف الموجود؛

    "ab+" - يتم فتح أو إنشاء ملف ثنائي لتصحيح المعلومات الموجودة وإضافة معلومات جديدة إلى نهاية الملف.

    تقوم الدالة بإرجاع NULL في متغير الملف f إذا تم فتح الملف بشكل غير ناجح. بعد فتح الملف، يكون البايت 0 متاحًا، ومؤشر الملف هو 0، وتتغير قيمته عند قراءته أو كتابته بعدد البايتات المقروءة (المكتوبة). القيمة الحالية لمؤشر الملف هي رقم البايت الذي ستحدث منه عملية القراءة أو الكتابة.

    ل إغلاقالملف مخصص لوظيفة fclos

    int f Close(FILE *filename);

    يُرجع 0 إذا تم إغلاق الملف بنجاح، ويُرجع NULL بخلاف ذلك.

    وظيفة الإزالة مخصصة لـ إزالةملفات.

    int إزالة(const char *filename);

    تقوم هذه الوظيفة بحذف ملف يسمى filenema من القرص. يجب إغلاق الملف المراد حذفه. تقوم الدالة بإرجاع قيمة غير صفرية إذا تعذر حذف الملف.

    ل إعادة تسميةالملفات، فإن وظيفة إعادة التسمية مخصصة:

    int rename(const char *oldfilename, const char *newfilename);

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

    قراءةمن ملف ثنائي يتم باستخدام وظيفة fread:

    fread(void *ptr, size, n, FILE *filename);

    تقرأ الدالة fread n من العناصر ذات الحجم من اسم الملف إلى مصفوفة ptr. ترجع الدالة عدد العناصر المقروءة. بعد القراءة من ملف، يتم إزاحة المؤشر بمقدار n*size بايت.

    سِجِلّيتم إجراء ملف ثنائي باستخدام الدالة fwrite:

    fwrite(const void *ptr, size, n, FILE *filename);

    تقوم الدالة fwrite بالكتابة على اسم الملف من مصفوفة ptr مكونة من عناصر n ذات حجم الحجم. ترجع الدالة عدد العناصر المكتوبة. بعد كتابة المعلومات إلى الملف، يتم إزاحة المؤشر بمقدار n*size بايت.

    ل التحكم في نهاية الملفهناك وظيفة feof:

    int feof(FILE *filename);

    تقوم بإرجاع قيمة غير الصفر إذا تم الوصول إلى نهاية الملف.

    مثال:

    قم بإنشاء ملف ثنائي D:\\game\\noobs.dat واكتب فيه n عدد صحيح وn أرقام حقيقية.

    #تشمل "stdafx.h"

    #يشمل

    استخدام اسم للمحطة؛

    انت مين()

    setlocale(LC_ALL, "RUS");

    إنت ن، أنا؛

    مزدوج أ؛

    // إنشاء ملف ثنائي في وضع الكتابة

    f=fopen("D:\\game\\noobs.dat", "wb");

    // مدخل أعدادن

    cout<<"n="; cin>>ن;

    fwrite(&n, sizeof(int), 1, f);

    // حلقة لإدخال أرقام حقيقية

    ل (ط = 0؛ ط

    // أدخل الرقم الحقيقي التالي

    cout<<"a=";

    سين>>أ;

    // كتابة رقم حقيقي إلى ملف ثنائي

    fwrite(&a, sizeof(double), 1, f);

    // يغلق ملف

    fClose(f);

    نظام("وقفة");

    العودة 0؛

    مثال:

    اعرض محتويات الملف الثنائي D:\\game\\noobs.dat الذي تم إنشاؤه في المهمة السابقة

    #تشمل "stdafx.h"

    #يشمل

    استخدام اسم للمحطة؛

    انت مين()

    setlocale(LC_ALL, "RUS");

    إنت ن، أنا؛

    مزدوج *أ؛

    ملف *و؛ // وصف متغير الملف

    // فتح الملف الثنائي الموجود في وضع القراءة

    // اقرأ عددًا صحيحًا واحدًا من الملف إلى المتغير n

    // إخراج ن إلى الشاشة

    cout<<"n="<

    // تخصيص الذاكرة لمجموعة من الأرقام n

    أ=جديد مزدوج[ن];

    // اقرأ الأرقام الحقيقية من الملف إلى المصفوفة أ

    // إخراج المصفوفة إلى الشاشة

    ل (ط = 0؛ ط

    cout<

    cout<

    // يغلق ملف

    fClose(f);

    نظام("وقفة");

    العودة 0؛

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

    إنت ن، أنا؛

    مزدوج أ؛

    ملف *و؛

    f=fopen("D:\\game\\noobs.dat", "rb");

    ل (ط = 0؛ ط<15; i++)

    fClose(f);

    f=fopen("D:\\game\\noobs.dat", "rb");

    fread(&a, sizeof(double), 1, f);

    fClose(f);

    كما ترون، قراءة الأرقام من ملف ثم فتح الملف مرة أخرى ليست الطريقة الأكثر ملاءمة. سيكون استخدام الدالة fseek أكثر ملاءمة لتحريك مؤشر الملف إلى بايت معين.

    int fseek(FILE *filename, long int offset, int Origin);

    تقوم الوظيفة بتعيين مؤشر موضع الملف الحالي F وفقًا لقيم الأصل والإزاحة. تساوي معلمة الإزاحة عدد البايتات التي سيتم من خلالها إزاحة مؤشر الملف بالنسبة إلى الأصل المحدد بواسطة معلمة الأصل. يجب أن تكون قيمة معلمة الأصل إحدى قيم الإزاحة التالية المحددة في رأس stdio.h:

    SEEK_SET - من بداية الملف؛

    SEEK_CUR - من الموضع الحالي؛

    SEEK_END - من نهاية الملف.

    ترجع الدالة قيمة صفر إذا كانت العملية ناجحة، وقيمة غير صفرية إذا فشلت الإزاحة.

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

    مثال

    في الملف الثنائي D:\\game\\noobs.dat الذي تم إنشاؤه مسبقًا، قم بتبديل الأرقام الحقيقية الأكبر والأصغر.

    تتكون خوارزمية حل المشكلة من المراحل التالية:

      قراءة الحقائق من ملف إلى المصفوفة أ.

      ابحث في المصفوفة a عن القيم القصوى (max) و الدنيا (min) و أرقامها (imax, imin).

      تحريك مؤشر الملف إلى الحد الأقصى للقيمة وكتابة الحد الأدنى.

      تحريك مؤشر الملف إلى الحد الأدنى للقيمة والكتابة بحد أقصى.

    وفيما يلي نص برنامج حل المشكلة بالتعليقات.

    #تشمل "stdafx.h"

    #يشمل

    استخدام اسم للمحطة؛

    انت مين()

    setlocale(LC_ALL, "RUS");

    إنت ن، أنا، إيماكس، إيمين؛

    مزدوج * أ، الحد الأقصى، الحد الأدنى؛

    ملف *و؛

    // فتح ملف في وضع القراءة والكتابة

    f=fopen("D:\\game\\noobs.dat", "rb+");

    // قراءة الرقم من الملف إلى المتغير n

    // الأعداد الحقيقية في الملف

    fread(&n, sizeof(int), 1, f);

    cout<<"n="<

    // تخصيص الذاكرة لتخزين الأعداد الحقيقية،

    // والتي سيتم تخزينها في المصفوفة أ

    أ=جديد مزدوج[ن];

    // القراءة من الملف إلى المصفوفة والأرقام الحقيقية

    fread(a, sizeof(double), n, f);

    // ابحث عن الحد الأقصى والحد الأدنى من العناصر

    // في المصفوفة a ومؤشراتها

    لـ (imax=imin=0, max=min=a, i=1; i

    إذا (أ[i]>الحد الأقصى)

    max=a[i];

    إذا (أ[i]

    دقيقة=أ[i];

    // متحرك المؤشر ل أقصى عنصر

    fseek(f, sizeof(int)+imax*sizeof(double), SEEK_SET);

    //اكتب الحد الأدنى بدلاً من الحد الأقصى لعنصر الملف

    fwrite(&min, sizeof(double), 1, f);

    // متحرك المؤشر ل الحد الأدنى عنصر

    fseek(f, sizeof(int)+imin*sizeof(double), SEEK_SET);

    // سجل الحد الأقصى بدلاً من الحد الأدنى لعنصر الملف

    fwrite(&max, sizeof(double), 1, f);

    // إغلاق الملف

    fClose(f);

    //ذاكرة متاحة

    يمسح [ ]أ؛

    نظام("وقفة");