الإدخال/الإخراج لملفات C: إنشاء ملف وفتحه وقراءته وكتابته وإغلاقه

⚡ ملخص ذكي

تقوم معالجة الملفات في لغة C بتخزين البيانات الدائمة على القرص من خلال مكتبة stdio، والتي تفتح ملفًا باستخدام fopen، وتكتب باستخدام fputc أو fputs أو fprintf، وتقرأ باستخدام fgetc أو fgets أو fscanf، وتغلقه باستخدام fclose.

  • 📁 أوضاع الملفات: تحدد سلسلة الوضع التي يتم تمريرها إلى fopen - r أو w أو a أو r+ أو w+ أو a+ - ما إذا كان سيتم قراءة الملف أو الكتابة فوقه أو إلحاقه.
  • ✍️ كتابة البيانات: يكتب الأمر fputc حرفًا واحدًا، ويكتب الأمر fputs سلسلة نصية، ويكتب الأمر fprintf نصًا منسقًا إلى مؤشر الملف.
  • ؟؟؟؟ قراءة البيانات: يقرأ fgetc حرفًا، ويقرأ fgets سطرًا في مخزن مؤقت، ويقوم fscanf بتحليل الرموز المنسقة من الملف.
  • 🔒 إغلاق الملفات: تقوم الدالة fclose بتفريغ البيانات المخزنة مؤقتًا وتحرير الملف، وتعيد القيمة 0 في حالة النجاح و EOF في حالة الفشل.
  • 🔁 الإدخال/الإخراج التفاعلي: تتعامل الدالتان getc و putc مع حرف واحد في كل مرة، حيث تنقلان المدخلات مباشرة إلى ملف ثم تعيدانها مرة أخرى.
  • 🤖 مساعدة الذكاء الاصطناعي: يقوم GitHub Copilot والمساعدون المدعومون بالذكاء الاصطناعي بإنشاء إجراءات fopen و fprintf و fgets والإبلاغ عن عمليات التحقق من القيم الفارغة المفقودة أو الملفات غير المغلقة.

ملفات C الإدخال/الإخراج

ج إدارة الملفات

يمكن استخدام الملف لتخزين كمية كبيرة من البيانات الدائمة. ومثل العديد من اللغات الأخرى، توفر لغة C إدارة الملفات التالية وظائف,

  1. إنشاء ملف
  2. فتح ملف
  3. قراءة ملف
  4. الكتابة إلى ملف
  5. إغلاق ملف

فيما يلي أهم وظائف إدارة الملفات المتوفرة في "C"،

وظيفة غرض
فوبين () إنشاء ملف أو فتح ملف موجود
فكلوز () إغلاق ملف
فبرينتف () كتابة كتلة من البيانات إلى ملف
فسكانف () قراءة بيانات كتلة من ملف
جيتك () يقرأ حرف واحد من ملف
بوتك () يكتب حرف واحد إلى ملف
الحصول ث () يقرأ عددا صحيحا من ملف
وضع () كتابة عدد صحيح إلى ملف
فسيك () يضبط موضع مؤشر الملف على موقع محدد
فتيل () إرجاع الموضع الحالي لمؤشر الملف
الترجيع () يضبط مؤشر الملف في بداية الملف

كيفية إنشاء ملف

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

لإنشاء ملف في برنامج "C" يتم استخدام بناء الجملة التالي،

FILE *fp;
fp = fopen ("file_name", "mode");

في بناء الجملة أعلاه، الملف عبارة عن بنية بيانات تم تعريفها في المكتبة القياسية.

fopen هي وظيفة قياسية تُستخدم لفتح ملف.

  • إذا لم يكن الملف موجودا على النظام، فسيتم إنشاؤه ثم فتحه.
  • إذا كان الملف موجودًا بالفعل على النظام، فسيتم فتحه مباشرة باستخدام هذه الوظيفة.

fp هو ملف مؤشر والذي يشير إلى ملف النوع.

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

وضع الملف الوصف
r فتح ملف للقراءة. إذا كان الملف في وضع القراءة، فلن يتم حذف أي بيانات إذا كان الملف موجودًا بالفعل على النظام.
w فتح ملف للكتابة. إذا كان الملف في وضع الكتابة، فسيتم إنشاء ملف جديد إذا لم يكن الملف موجودًا على الإطلاق. إذا كان الملف موجودًا بالفعل على النظام، فسيتم اقتطاع جميع البيانات الموجودة داخل الملف، ويتم فتحه لأغراض الكتابة.
a افتح ملفًا في وضع الإلحاق. إذا كان الملف في وضع الإلحاق، فسيتم فتحه. ولن يتغير محتواه.
r+ مفتوح للقراءة والكتابة من البداية
w+ مفتوحة للقراءة والكتابة، والكتابة فوق ملف
a+ مفتوحة للقراءة والكتابة، وإلحاق الملف

في الصيغة المعطاة، يتم تحديد اسم الملف والوضع على النحو التالي: سلاسل لذا يجب دائمًا وضعها بين علامتي اقتباس مزدوجتين.

فمثلا:

#include <stdio.h>
int main() {
FILE *fp;
fp  = fopen ("data.txt", "w");
}

الإخراج:

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

أنشئ ملفًا في مخرجات برنامج C

يمكنك تحديد المسار الذي تريد إنشاء ملفك فيه

#include <stdio.h>
int main() {
FILE *fp;
fp  = fopen ("D://data.txt", "w");
}

أنشئ ملفًا بمسار محدد في لغة C

كيفية إغلاق ملف

ينبغي دائمًا إغلاق الملف عند انتهاء العمليات التي تتم عليه. وهذا يعني انتهاء محتويات الملف والروابط المؤدية إليه. وهذا يمنع حدوث تلف عرضي للملف.

يوفر "C" وظيفة fclose لإجراء عملية إغلاق الملف. يكون بناء جملة fclose على النحو التالي،

fclose (file_pointer);

فمثلا:

FILE *fp;
fp  = fopen ("data.txt", "r");
fclose (fp);

تأخذ الدالة fclose مؤشر ملف كمعامل. ثم تُغلق الدالة الملف المرتبط بهذا المؤشر. تُرجع الدالة القيمة 0 في حال نجاح الإغلاق، وEOF (نهاية الملف) في حال حدوث خطأ أثناء إغلاق الملف.

بعد إغلاق الملف، يمكن أيضًا استخدام نفس مؤشر الملف مع ملفات أخرى.

في البرمجة C، يتم إغلاق الملفات تلقائيًا عند إنهاء البرنامج. يعد إغلاق الملف يدويًا عن طريق كتابة دالة fclose ممارسة برمجة جيدة.

الكتابة في ملف

في لغة C، عندما تكتب إلى ملف، يجب إضافة أحرف السطر الجديد '\n' بشكل صريح.

توفر مكتبة stdio الوظائف الضرورية للكتابة إلى ملف:

  • fputc(char, file_pointer): يكتب حرفًا إلى الملف الذي يشير إليه file_pointer.
  • fputs(str, file_pointer): يقوم هذا الأمر بكتابة سلسلة نصية إلى الملف الذي يشير إليه file_pointer.
  • fprintf(file_pointer, str, variable_lists): تقوم هذه الدالة بطباعة سلسلة نصية في الملف الذي يشير إليه المؤشر file_pointer. يمكن أن تتضمن السلسلة النصية، اختيارياً، مُحدِّدات التنسيق وقائمة المتغيرات variable_lists.

يوضح البرنامج أدناه كيفية إجراء الكتابة إلى ملف:

الدالة fputc():

#include <stdio.h>
int main() {
        int i;
        FILE * fptr;
        char fn[50];
        char str[] = "Guru99 Rocks\n";
        fptr = fopen("fputc_test.txt", "w"); // "w" defines "writing mode"
        for (i = 0; str[i] != '\n'; i++) {
            /* write to file using fputc() function */
            fputc(str[i], fptr);
        }
        fclose(fptr);
        return 0;
    }

الإخراج:

مخرجات الدالة fputc() في لغة C

يكتب البرنامج المذكور أعلاه حرفًا واحدًا في ملف fputc_test.txt حتى يصل إلى رمز السطر التالي "\n"، مما يشير إلى أن الجملة قد كُتبت بنجاح. وتتلخص العملية في أخذ كل حرف من المصفوفة وكتابته في الملف.

محتوى ملف fputc_test.txt مكتوب بلغة C

  1. في البرنامج أعلاه، قمنا بإنشاء وفتح ملف يسمى fputc_test.txt في وضع الكتابة وإعلان السلسلة التي سيتم كتابتها في الملف.
  2. نقوم بعملية الكتابة حرفًا بحرف باستخدام حلقة for ونضع كل حرف في ملفنا حتى نواجه الحرف "\n" ثم نغلق الملف باستخدام الدالة fclose.

وظيفة fputs ():

#include <stdio.h>
int main() {
        FILE * fp;
        fp = fopen("fputs_test.txt", "w+");
        fputs("This is Guru99 Tutorial on fputs,", fp);
        fputs("We don't need to use for loop\n", fp);
        fputs("Easier than fputc function\n", fp);
        fclose(fp);
        return (0);
    }

الإخراج:

مخرجات الدالة fputs() في لغة C

محتوى ملف fputs_test.txt بلغة C

  1. في البرنامج أعلاه، قمنا بإنشاء وفتح ملف يسمى fputs_test.txt في وضع الكتابة.
  2. بعد ذلك، نقوم بعملية كتابة باستخدام الدالة fputs() عن طريق كتابة ثلاث سلاسل نصية مختلفة
  3. ثم يتم إغلاق الملف باستخدام الدالة fClose.

الدالة fprintf():

#include <stdio.h>
    int main() {
        FILE *fptr;
        fptr = fopen("fprintf_test.txt", "w"); // "w" defines "writing mode"
        /* write to file */
        fprintf(fptr, "Learning C with Guru99\n");
        fclose(fptr);
        return 0;
    }

الإخراج:

إخراج الدالة fprintf() في لغة C

محتوى ملف fprintf_test.txt بلغة C

  1. في البرنامج أعلاه قمنا بإنشاء وفتح ملف يسمى fprintf_test.txt في وضع الكتابة.
  2. بعد إجراء عملية الكتابة باستخدام الدالة fprintf() عن طريق كتابة سلسلة، يتم إغلاق الملف باستخدام الدالة fclose.

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

هناك ثلاث وظائف مختلفة مخصصة لقراءة البيانات من الملف

  • الدالة fgetc(file_pointer): تُعيد هذه الدالة الحرف التالي من الملف الذي يُشير إليه مؤشر الملف. وعند الوصول إلى نهاية الملف، تُرسل إشارة نهاية الملف (EOF).
  • fgets(buffer, n, file_pointer): يقرأ n-1 حرفًا من الملف ويخزن السلسلة في مخزن مؤقت حيث يتم إلحاق الحرف الفارغ '\0' كآخر حرف.
  • الدالة fscanf(file_pointer, conversion_specifiers, variable_adresses): تُستخدم لتحليل البيانات وقراءتها. تقرأ هذه الدالة الأحرف من الملف وتُسندها إلى قائمة من مؤشرات المتغيرات variable_adresses باستخدام مُحدِّدات التحويل. تجدر الإشارة إلى أنه كما هو الحال مع الدالة scanf، تتوقف fscanf عن قراءة السلسلة النصية عند مصادفة مسافة أو سطر جديد.

يوضح البرنامج التالي القراءة من ملف fputs_test.txt باستخدام وظائف fgets() وfscanf() وfgetc() على التوالي:

#include <stdio.h>
int main() {
        FILE * file_pointer;
        char buffer[30], c;

        file_pointer = fopen("fprintf_test.txt", "r");
        printf("----read a line----\n");
        fgets(buffer, 50, file_pointer);
        printf("%s\n", buffer);

        printf("----read and parse data----\n");
        file_pointer = fopen("fprintf_test.txt", "r"); //reset the pointer
        char str1[10], str2[2], str3[20], str4[2];
        fscanf(file_pointer, "%s %s %s %s", str1, str2, str3, str4);
        printf("Read String1 |%s|\n", str1);
        printf("Read String2 |%s|\n", str2);
        printf("Read String3 |%s|\n", str3);
        printf("Read String4 |%s|\n", str4);

        printf("----read the entire file----\n");

        file_pointer = fopen("fprintf_test.txt", "r"); //reset the pointer
        while ((c = getc(file_pointer)) != EOF) printf("%c", c);

        fclose(file_pointer);
        return 0;
    }

النتيجة:

----read a line----
Learning C with Guru99

----read and parse data----
Read String1 |Learning|
Read String2 |C|
Read String3 |with|
Read String4 |Guru99|
----read the entire file----
Learning C with Guru99

قراءة البيانات من ملف في مخرجات لغة C

  1. في البرنامج أعلاه، قمنا بفتح الملف المسمى "fprintf_test.txt" الذي كُتب مسبقًا باستخدام الدالة fprintf()، ويحتوي على "تعلم لغة C مع Guruسلسلة نصية طولها 99 بوصة. نقرأها باستخدام الدالة fgets() التي تقرأ سطرًا بسطر، حيث يجب أن يكون حجم المخزن المؤقت كافيًا للتعامل مع السطر بأكمله.
  2. نعيد فتح الملف لإعادة ضبط مؤشر الملف ليشير إلى بدايته. أنشئ متغيرات نصية متعددة لمعالجة كل كلمة على حدة. اطبع المتغيرات لعرض محتوياتها. تُستخدم الدالة fscanf() بشكل أساسي لـtract وتحليل البيانات من ملف.
  3. أعد فتح الملف لإعادة تعيين ملف المؤشر ليشير إلى بداية الملف. اقرأ البيانات واطبعها من حرف الملف بحرف باستخدام الدالة getc() حتى تتم مواجهة عبارة EOF
  4. بعد إجراء عملية قراءة الملف باستخدام المتغيرات المختلفة، قمنا بإغلاق الملف مرة أخرى باستخدام الدالة fclose.

ملف تفاعلي للقراءة والكتابة باستخدام getc وputc

هذه هي أبسط عمليات الملفات. Getc تعني الحصول على الحرف، وputc تعني وضع الحرف. تُستخدم هاتان الدالتان للتعامل مع حرف واحد فقط في كل مرة.

يوضح البرنامج التالي وظائف التعامل مع الملفات في برمجة "C":

#include <stdio.h>
int main() {
        FILE * fp;
        char c;
        printf("File Handling\n");
        //open a file
        fp = fopen("demo.txt", "w");
        //writing operation
        while ((c = getchar()) != EOF) {
            putc(c, fp);
        }
        //close file
        fclose(fp);
        printf("Data Entered:\n");
        //reading
        fp = fopen("demo.txt", "r");
        while ((c = getc(fp)) != EOF) {
            printf("%c", c);
        }
        fclose(fp);
        return 0;
    }

الإخراج:

قراءة وكتابة الملفات التفاعلية في مخرجات لغة C

معالجة مخرجات الملفات باستخدام الدالتين getc و putc في لغة C

  1. في البرنامج أعلاه قمنا بإنشاء وفتح ملف يسمى العرض التوضيحي في وضع الكتابة.
  2. بعد إجراء عملية الكتابة، يتم إغلاق الملف باستخدام الدالة fclose.
  3. لقد فتحنا مرة أخرى ملفًا يحتوي الآن على بيانات في وضع القراءة. سيتم تنفيذ حلقة while حتى يتم العثور على نهاية الملف. بمجرد العثور على نهاية الملف، سيتم إنهاء العملية وسيتم عرض البيانات باستخدام دالة printf.
  4. بعد إجراء عملية القراءة، يتم إغلاق الملف مرة أخرى باستخدام الدالة fclose.

الأسئلة الشائعة

يقوم وضع النص بترجمة أحرف السطر الجديد لتتوافق مع نظام التشغيل، بينما يقوم الوضع الثنائي، الذي يُفتح باستخدام "rb" أو "wb"، بكتابة البايتات كما هي تمامًا. استخدم الوضع الثنائي للصور أو الصوت أو أي بيانات أخرى يجب الحفاظ على ترتيب البايتات فيها بدقة.

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

يقوم وضع الكتابة "w" باقتطاع محتوى الملف الموجود قبل الكتابة، ثم يُنشئ الملف في حال عدم وجوده. أما وضع الإلحاق "a" فيحتفظ بالبيانات الموجودة ويضيف المحتوى الجديد في النهاية، فلا يتم فقدان أي بيانات مخزنة مسبقًا.

تُحرّك الدالة fseek مؤشر الملف إلى إزاحة بايت مُقاسة من SEEK_SET أو SEEK_CUR أو SEEK_END. تُعيد الدالة ftell موضع البايت الحالي للمؤشر، بينما تُعيد الدالة rewind المؤشر إلى بداية الملف. تُتيح هذه الدوال معًا الوصول العشوائي بدلًا من القراءة التسلسلية.

يقرأ الأمر fgets سطرًا كاملاً، ثم يتوقف.ping عند سطر جديد أو بعد n-1 حرفًا، لذا فهو يراعي حجم المخزن المؤقت. يقرأ fscanf الرموز المنسقة والمفصولة بمسافات، وقد يتجاوز سعة مصفوفة قصيرة. لقراءة أسطر كاملة بأمان، يُعد fgets الخيار الأفضل.

EOF هو قيمة ثابتة، عادةً ما تكون -1، تُشير إلى نهاية الملف. تُعيد دوال القراءة مثل getc و fgetc و fscanf قيمة EOF بمجرد عدم وجود بيانات أخرى، ولهذا السبب تُقارن الحلقات نتيجتها بقيمة EOF لإيقاف القراءة.

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

مساعد الطيار جيثب يكتب هذا البرنامج شيفرة معالجة الملفات بلغة C، مقترحًا كتلًا كاملة من دوال fopen و fputs و fscanf بناءً على تعليق قصير أو اسم دالة. غالبًا ما يضيف استدعاء fclose المطابق وفحصًا للأخطاء، مع ذلك، يُنصح بمراجعة المنطق المُولّد.

تلخيص هذه التدوينة بـ: