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

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

جزء من قسم Logic & Flow في رحلة C على Coddy — الدرس 53 من 63.

challenge icon

التحدي

سهل

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

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

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

يجب على برنامجك القيام بما يلي:

  1. استخدام نفس تعريف هيكل Contact من الدروس السابقة مع الأعضاء التالية:
    • مصفوفة أحرف name بحجم 50
    • مصفوفة أحرف phone بحجم 20
    • مصفوفة أحرف email بحجم 40
    • عدد صحيح age
  2. استخدام نفس دالة createContact من الدروس السابقة التي تقوم بـ:
    • تخصيص ذاكرة ديناميكياً لهيكل Contact
    • تهيئة جميع الأعضاء إلى قيم افتراضية
    • إرجاع مؤشر (pointer) إلى جهة الاتصال
  3. كتابة دالة populateContact تقوم بـ:
    • تأخذ مؤشراً إلى هيكل Contact كمعامل لها
    • تستخدم fgets() لقراءة كل حقل نصي (name، phone، email) بحيث يتم قبول الأسماء التي تحتوي على مسافات
    • تستخدم strcspn() لإزالة حرف السطر الجديد الزائد من كل حقل نصي بعد قراءته
    • تستخدم scanf("%d", ...) لقراءة حقل العمر الصحيح
    • ملاحظة: هذا الإصدار من populateContact لا يتضمن التحقق من طول رقم الهاتف — لا تقم بإضافته، حيث تستخدم مدخلات الاختبار أرقام هواتف قصيرة مثل 555-1234
  4. كتابة دالة باسم displayContact تقوم بـ:
    • تأخذ مؤشراً ثابتاً (constant pointer) إلى هيكل 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 function):
    • إنشاء جهة اتصال باستخدام دالة createContact
    • التحقق مما إذا كان إنشاء جهة الاتصال ناجحاً
    • استدعاء دالة populateContact لتعبئة بيانات جهة الاتصال
    • استدعاء دالة displayContact لإظهار معلومات جهة الاتصال المنسقة
    • تحرير الذاكرة المخصصة ديناميكياً
    • طباعة Program completed successfully

يوضح هذا التحدي كيفية إنشاء دالة عرض تأخذ مؤشراً ثابتاً إلى هيكل، مما يضمن أن الدالة لا يمكنها تعديل البيانات الأصلية. ستتدرب على استخدام fgets() لقراءة السلاسل النصية التي تحتوي على مسافات، و strcspn() لإزالة أسطر السطر الجديد الزائدة، وعامل السهم (arrow operator) للوصول إلى أعضاء الهيكل من خلال مؤشر، و 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;
}

جميع دروس Logic & Flow