تجميع كل الأجزاء معاً
جزء من قسم Logic & Flow في رحلة C على Coddy — الدرس 54 من 63.
التحدي
سهلأكمل نظام إدارة جهات الاتصال الخاص بك من خلال دمج جميع الوظائف التي أنشأتها في الدروس السابقة. يجب أن يقوم برنامجك بما يلي:
- استخدام نفس تعريف هيكل
Contactمن الدروس السابقة مع الأعضاء التالية:- مصفوفة أحرف
nameبحجم 50 - مصفوفة أحرف
phoneبحجم 20 - مصفوفة أحرف
emailبحجم 40 - عدد صحيح
age
- مصفوفة أحرف
- استخدام نفس دالة
createContactمن الدروس السابقة التي تقوم بـ:- تخصيص الذاكرة ديناميكيًا لهيكل
Contact - تهيئة جميع الأعضاء للقيم الافتراضية
- إرجاع مؤشر (pointer) إلى جهة الاتصال
- تخصيص الذاكرة ديناميكيًا لهيكل
- استخدام نفس دالة
populateContactمن الدروس السابقة التي تقوم بـ:- تأخذ مؤشرًا إلى هيكل
Contactكمعامل لها - تطلب مدخلات من المستخدم وتملأ جميع حقول جهة الاتصال
- تتحقق من صحة بيانات الإدخال
- تأخذ مؤشرًا إلى هيكل
- كتابة دالة
displayContactتقوم بـ:- تأخذ مؤشرًا ثابتًا (constant pointer) إلى هيكل
Contactكمعامل لها - تطبع كل حقل في سطر خاص به بهذا التنسيق الدقيق:
Name: John
Phone: 555-1234
Email: john@email.com
Age: 25
- تأخذ مؤشرًا ثابتًا (constant pointer) إلى هيكل
- كتابة دالة باسم
updateContactتقوم بـ:- تأخذ مؤشرًا إلى هيكل
Contactكمعامل لها - لا تعيد شيئًا (void)
- تطلب من المستخدم اختيار الحقل الذي يرغب في تحديثه عن طريق طباعة:
What would you like to update?1. Name2. Phone3. Email4. AgeEnter choice (1-4):
- تقرأ اختيار المستخدم وتحدث الحقل المقابل:
- إذا كان الاختيار 1: تطبع
Enter new name:وتحدث الاسم - إذا كان الاختيار 2: تطبع
Enter new phone:وتحدث الهاتف - إذا كان الاختيار 3: تطبع
Enter new email:وتحدث البريد الإلكتروني - إذا كان الاختيار 4: تطبع
Enter new age:وتحدث العمر - إذا كان الاختيار غير صالح (ليس من 1-4): تطبع
Invalid choice
- إذا كان الاختيار 1: تطبع
- بعد التحديث الناجح، تطبع
Contact updated successfully
- تأخذ مؤشرًا إلى هيكل
- في الدالة الرئيسية (main function)، قم بتنفيذ سير عمل كامل لإدارة جهات الاتصال:
- إنشاء جهة اتصال باستخدام دالة
createContact - التحقق مما إذا كان إنشاء جهة الاتصال ناجحًا
- استدعاء دالة
populateContactلملء بيانات جهة الاتصال الأولية - طباعة
--- Initial Contact --- - استدعاء دالة
displayContactلعرض معلومات جهة الاتصال الأولية - طباعة
--- Updating Contact --- - استدعاء دالة
updateContactلتعديل حقل واحد - طباعة
--- Updated Contact --- - استدعاء دالة
displayContactمرة أخرى لعرض معلومات جهة الاتصال المحدثة - تحرير الذاكرة المخصصة ديناميكيًا
- طباعة
Contact management completed
- إنشاء جهة اتصال باستخدام دالة
ملاحظة: تستخدم دالة displayContact في هذا الدرس تنسيقًا بسيطًا — سطر واحد لكل حقل بدون تفاصيل إضافية أو وحدات (على سبيل المثال، يتم طباعة العمر كرقم مجرد، وليس "25 years old"). تأكد من أن مخرجاتك تطابق التنسيق الموضح أعلاه تمامًا، حيث تعتمد حالات الاختبار على ذلك.
يجمع هذا التحدي النهائي جميع مكونات نظام إدارة جهات الاتصال الخاص بك: تعريف الهيكل، تخصيص الذاكرة الديناميكي، إدخال البيانات والتحقق من صحتها، العرض المنسق، وتعديل البيانات. ستوضح دورة الحياة الكاملة لهيكل مخصص ديناميكيًا من الإنشاء إلى التنظيف، مع ممارسة تنظيم الدوال والاستخدام الصحيح للمؤشرات طوال العملية بأكملها.
جرّب بنفسك
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Contact {
char name[50];
char phone[20];
char email[40];
int age;
};
struct Contact* createContact() {
struct Contact* contact = (struct Contact*)malloc(sizeof(struct Contact));
if (contact != NULL) {
strcpy(contact->name, "");
strcpy(contact->phone, "");
strcpy(contact->email, "");
contact->age = 0;
}
return contact;
}
void populateContact(struct Contact* contactPtr) {
printf("Enter name: ");
fgets(contactPtr->name, sizeof(contactPtr->name), stdin);
contactPtr->name[strcspn(contactPtr->name, "\n")] = '\0';
printf("Enter phone: ");
fgets(contactPtr->phone, sizeof(contactPtr->phone), stdin);
contactPtr->phone[strcspn(contactPtr->phone, "\n")] = '\0';
printf("Enter email: ");
fgets(contactPtr->email, sizeof(contactPtr->email), stdin);
contactPtr->email[strcspn(contactPtr->email, "\n")] = '\0';
printf("Enter age: ");
scanf("%d", &contactPtr->age);
}
void displayContact(const struct Contact *contactPtr) {
printf("=== CONTACT DETAILS ===\n");
printf("Name: %s\n", contactPtr->name);
printf("Phone: %s\n", contactPtr->phone);
printf("Email: %s\n", contactPtr->email);
printf("Age: %d years old\n", contactPtr->age);
printf("========================\n");
printf("Name length: %lu characters\n", strlen(contactPtr->name));
if (contactPtr->age >= 0 && contactPtr->age <= 12) {
printf("Generation: Child\n");
} else if (contactPtr->age >= 13 && contactPtr->age <= 19) {
printf("Generation: Teenager\n");
} else if (contactPtr->age >= 20 && contactPtr->age <= 39) {
printf("Generation: Young Adult\n");
} else if (contactPtr->age >= 40 && contactPtr->age <= 59) {
printf("Generation: Middle-aged Adult\n");
} else if (contactPtr->age >= 60) {
printf("Generation: Senior\n");
}
if (strchr(contactPtr->email, '@') != NULL) {
printf("Email format: Valid\n");
} else {
printf("Email format: Invalid\n");
}
}
int main() {
struct Contact* contact = createContact();
if (contact != NULL) {
populateContact(contact);
displayContact(contact);
free(contact);
printf("Program completed successfully\n");
}
return 0;
}جميع دروس Logic & Flow
1أساسيات المؤشرات
ما هو المؤشر؟الإعلان عن المؤشراتعامل العنوان (&)عامل إلغاء المرجعية (*)مؤشرات NULLمراجعة: أساسيات المؤشرات4مشروع: أداة نصوص بسيطة
نظرة عامة على المشروععد الأحرف2المؤشرات والمصفوفات
أسماء المصفوفات كمؤشراتعناصر المصفوفة - المؤشراتالعمليات الحسابية على المؤشراتمقارنة المؤشراتمراجعة: التنقل في المصفوفة باستخدام المؤشرات5المؤشرات والدوال
التمرير بالقيمةتمرير المؤشرات إلى الدوالتعديل المتغيرات عبر المؤشراتمثال كلاسيكي: التبديلتمرير المصفوفات إلى الدوالملخص: وسائط المؤشرات في الدوال8الهياكل والمؤشرات
المؤشرات إلى الهياكلعامل السهم (->)تمرير الهياكل بالقيمةتمرير مؤشرات الهياكلالتخصيص الديناميكي للهياكلمراجعة: تعديل الهياكل باستخدام المؤشرات11تحديات المراجعة النهائية
مراجعة: دمج السلاسل النصية الديناميكيمراجعة: مصفوفة من الـ Structsمراجعة: عداد تكرار الكلمات3مصفوفات الأحرف والسلاسل النصية
السلاسل النصية كمصفوفات charالمُنهي الصفري (Null Terminator)إدخال السلاسل النصية باستخدام scanfاستخدام strlen()استخدام strcpy()استخدام strcat()استخدام strcmp()مراجعة: دوال السلاسل النصية الأساسية6إدارة الذاكرة
ذاكرة Stack مقابل Heapالتخصيص الديناميكي - malloc()استخدام sizeof() للتخصيصالتحقق من فشل التخصيصتحرير الذاكرة باستخدام free()التخصيص باستخدام calloc()ملخص: المصفوفة الديناميكية9مشروع: إدخال جهة اتصال بسيطة
مشروع: تعريف Struct جهة الاتصالدالة لإنشاء جهة اتصال