كيفية استخدام دالة fgets في لغة C لقراءة السلاسل النصية بأمان وتفادي تجاوز البافر

1. المقدمة

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

2. الطريقة الأساسية لاستخدام دالة fgets

2.1 بناء دالة fgets والمعاملات الخاصة بها

البنية الأساسية لدالة fgets هي كما يلي:

char *fgets(char *str, int n, FILE *stream);
  • str: المصفوفة (البافر) التي سيتم تخزين النص المدخل فيها
  • n: الحد الأقصى لعدد الأحرف التي سيتم قراءتها (حجم البافر)
  • stream: تيار الإدخال (عادةً stdin)

2.2 مثال عملي على استخدام fgets

فيما يلي مثال بسيط لاستخدام fgets:

char buffer[50];
fgets(buffer, 50, stdin);
printf("入力された文字列:%s", buffer);

يقوم هذا الكود بقراءة ما يصل إلى 49 حرفاً من المستخدم (مع الأخذ في الاعتبار أن الحرف الأخير هو null) ويطبع النص المدخل.

3. مزايا وعيوب fgets

3.1 الأمان مقارنة بدالة gets

دالة gets معرضة لخطر تجاوز البافر (buffer overflow) مما يشكل تهديداً أمنياً كبيراً. بينما دالة fgets تسمح بتحديد عدد الأحرف التي سيتم قراءتها، مما يمنع حدوث تجاوز في الذاكرة.

3.2 مشكلة قراءة محرف السطر الجديد والتعامل مع البافر

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

4. كيفية التعامل مع الإدخال الآمن

4.1 طريقة إزالة محرف السطر الجديد

عند استخدام fgets، قد تحتوي السلسلة المقروءة على محرف السطر الجديد. لإزالته يمكن إضافة الكود التالي:

char *newline = strchr(buffer, 'n');
if (newline) {
    *newline = ' ';
}

بهذه الطريقة يتم استبدال محرف السطر الجديد بمحرف null لجعل السلسلة أكثر نظافة.

4.2 كيفية تفريغ البافر (مسح الإدخال المتبقي)

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

while ((getchar()) != 'n' && !feof(stdin));

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

5. ملاحظات مهمة عند استخدام fgets

5.1 أهمية معالجة الأخطاء والاستثناءات

تعيد fgets مؤشر إلى النص إذا نجحت العملية، وتعيد NULL إذا فشلت. لذلك من الضروري معالجة الأخطاء بالشكل المناسب كما في المثال التالي:

if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
    // معالجة الخطأ
}

5.2 أفضل الممارسات

عند استخدام fgets، احرص دائماً على تحديد حجم البافر ومعالجة الأخطاء. تحقق من صحة البيانات المدخلة وتجنب تجاوز البافر لضمان أمان البرامج البرمجية.

6. أمثلة عملية باستخدام fgets

6.1 التحقق من الإدخال وتنقيته (Validation & Sanitization)

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

char input[10];
if (fgets(input, sizeof(input), stdin) != NULL) {
    // حذف محرف السطر الجديد
    char *newline = strchr(input, 'n');
    if (newline) {
        *newline = ' ';
    }

    // التحقق من أن الإدخال أرقام فقط
    if (strspn(input, "0123456789") == strlen(input)) {
        printf("入力された数字:%sn", input);
    } else {
        printf("無効な入力です。数字のみを入力してください。n");
    }
}

7. الخلاصة

تُعد دالة fgets أداة مفيدة لقراءة السلاسل النصية بأمان في لغة C، وتقلل بشكل كبير من مخاطر تجاوز البافر مقارنةً بالدالة gets. ومع ذلك، يجب الانتباه لمعالجة محرف السطر الجديد وتفريغ البافر عند الحاجة. باستخدام التقنيات المشروحة في هذا المقال، يمكنك تنفيذ معالجة إدخال آمنة وفعّالة.

年収訴求