Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

دالة لعرض جهة اتصال

جزء من قسم المنطق وتدفق التنفيذ في رحلة C على Coddy. الدرس 53 من 63.

challenge icon

التحدي

سهل

بناءً على نظام إدارة جهات الاتصال الذي أنشأته في الدروس السابقة، أنشئ دالة تعرض معلومات جهة الاتصال بطريقة منسّقة. يقدّم هذا الدرس ثلاث دوال جديدة للسلاسل النصية ستحتاج إليها: fgets() وstrcspn() وstrchr()؛ وسيتم شرح كل منها أدناه قبل المتطلبات.

الدوال الجديدة المستخدمة في هذا الدرس:

  • fgets(buffer, size, stdin): تقرأ سطرًا من الإدخال، بما في ذلك المسافات (بخلاف scanf التي تتوقف عند المسافات البيضاء). وتخزّن الإدخال في buffer، وتقرأ بحد أقصى size - 1 من المحارف. كما تخزّن محرف السطر الجديد '\n' في النهاية.
  • strcspn(str, "\n"): تُرجع فهرس أول ظهور لـ '\n' في str. وتُستخدم لإزالة محرف السطر الجديد الموجود في نهاية السلسلة بعد استخدام fgets: str[strcspn(str, "\n")] = '\0';
  • strchr(str, ch): تبحث عن المحرف ch في str وتُرجع مؤشرًا إلى موقعه، أو NULL إذا لم يتم العثور عليه.

يجب أن ينفّذ برنامجك ما يلي:

  1. استخدم تعريف Contact نفسه من الدروس السابقة، مع الأعضاء التالية:
    • مصفوفة محارف name بحجم 50
    • مصفوفة محارف phone بحجم 20
    • مصفوفة محارف email بحجم 40
    • عدد صحيح age
  2. استخدم دالة createContact نفسها من الدروس السابقة، والتي:
    • تخصّص الذاكرة ديناميكيًا لبنية Contact
    • تهيّئ جميع الأعضاء إلى قيم افتراضية
    • تُرجع مؤشرًا إلى جهة الاتصال
  3. اكتب دالة populateContact التي:
    • تأخذ مؤشرًا إلى بنية Contact كمعامل لها
    • تستخدم fgets() لقراءة كل حقل نصي (الاسم والهاتف والبريد الإلكتروني) حتى يتم قبول الأسماء التي تحتوي على مسافات
    • تستخدم strcspn() لإزالة محرف السطر الجديد الموجود في نهاية كل حقل نصي بعد قراءته
    • تستخدم scanf("%d", ...) لقراءة حقل العمر الصحيح
    • ملاحظة: لا يتضمن هذا الإصدار من populateContact التحقق من طول رقم الهاتف: لا تضفه، لأن مدخلات الاختبار تستخدم أرقام هواتف قصيرة مثل 555-1234
  4. اكتب دالة باسم displayContact التي:
    • تأخذ مؤشرًا ثابتًا إلى بنية Contact كمعامل لها: const struct Contact *contactPtr
    • لا تُرجع أي شيء (void)
    • تطبع معلومات جهة الاتصال بالتنسيق الدقيق التالي:
      • === CONTACT DETAILS ===
      • Name: [name]
      • Phone: [phone]
      • Email: [email]
      • Age: [age] years old
      • ========================
    • بعد عرض المعلومات الأساسية، تحسب وتعرض تفاصيل إضافية:
      • تحسب طول الاسم باستخدام strlen() وتطبع: Name length: [length] characters
      • تحدّد فئة الجيل استنادًا إلى العمر وتطبع:
        • إذا كان العمر بين 0 و12: Generation: Child
        • إذا كان العمر بين 13 و19: Generation: Teenager
        • إذا كان العمر بين 20 و39: Generation: Young Adult
        • إذا كان العمر بين 40 و59: Generation: Middle-aged Adult
        • إذا كان العمر 60 أو أكثر: Generation: Senior
      • تتحقق مما إذا كان البريد الإلكتروني يحتوي على المحرف '@' باستخدام strchr()، وتطبع:
        • إذا تم العثور على '@': Email format: Valid
        • إذا لم يتم العثور على '@': Email format: Invalid
  5. في الدالة main:
    • أنشئ جهة اتصال باستخدام الدالة createContact
    • تحقق مما إذا كان إنشاء جهة الاتصال قد نجح
    • استدعِ الدالة populateContact لملء بيانات جهة الاتصال
    • استدعِ الدالة displayContact لعرض معلومات جهة الاتصال المنسّقة
    • حرّر الذاكرة المخصّصة ديناميكيًا
    • اطبع Program completed successfully

يوضّح هذا التحدي كيفية إنشاء دالة عرض تأخذ مؤشرًا ثابتًا إلى بنية، مما يضمن عدم تمكّن الدالة من تعديل البيانات الأصلية. ستتدرّب على استخدام fgets() لقراءة السلاسل النصية التي تحتوي على مسافات، واستخدام strcspn() لإزالة محارف السطر الجديد الموجودة في النهاية، واستخدام معامل السهم للوصول إلى أعضاء البنية من خلال مؤشر، واستخدام strchr() للبحث عن المحارف، واستخدام المنطق الشرطي لتصنيف البيانات. ويُعد استخدام const في تعريف المعامل ممارسة جيدة تمنع التعديل غير المقصود لبيانات جهة الاتصال داخل دالة العرض.

جرّب بنفسك

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char name[50];
    char phone[20];
    char email[40];
    int age;
} Contact;

Contact* createContact() {
    Contact* contact = (Contact*)malloc(sizeof(Contact));
    if (contact == NULL) {
        return NULL;
    }
    
    strcpy(contact->name, "");
    strcpy(contact->phone, "");
    strcpy(contact->email, "");
    contact->age = 0;
    
    return contact;
}

void populateContact(Contact* contactPtr) {
    printf("Enter name: ");
    scanf("%s", contactPtr->name);
    
    printf("Enter phone: ");
    scanf("%s", contactPtr->phone);
    
    printf("Enter email: ");
    scanf("%s", contactPtr->email);
    
    printf("Enter age: ");
    scanf("%d", &contactPtr->age);
    
    if (contactPtr->age < 0 || contactPtr->age > 120) {
        printf("Invalid age entered\n");
    } else if (strlen(contactPtr->phone) < 10) {
        printf("Invalid phone number\n");
    } else {
        printf("Contact populated successfully\n");
    }
}

int main() {
    Contact* contact = createContact();
    
    if (contact == NULL) {
        return 1;
    }
    
    populateContact(contact);
    
    printf("Contact Information:\n");
    printf("Name: %s\n", contact->name);
    printf("Phone: %s\n", contact->phone);
    printf("Email: %s\n", contact->email);
    printf("Age: %d\n", contact->age);
    
    free(contact);
    printf("Contact deleted successfully\n");
    
    return 0;
}

جميع دروس المنطق وتدفق التنفيذ

تدرّب بنفسك: مترجم C عبر الإنترنت