פונקציה להצגת איש קשר
חלק מהיחידה לוגיקה וזרימת תוכנית במסלול ה-C של Coddy. שיעור 53 מתוך 63.
אתגר
קלבהמשך למערכת ניהול אנשי הקשר שלך מהשיעורים הקודמים, כתוב פונקציה שמציגה את פרטי איש הקשר בפורמט מסודר. בשיעור הזה מוצגות שלוש פונקציות מחרוזת חדשות שתצטרך: 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אם הוא לא נמצא.
על התוכנית שלך:
- להשתמש באותה הגדרת
Contactמסוג struct מהשיעורים הקודמים, עם השדות:- מערך תווים בשם
nameבגודל 50 - מערך תווים בשם
phoneבגודל 20 - מערך תווים בשם
emailבגודל 40 - מספר שלם בשם
age
- מערך תווים בשם
- להשתמש באותה פונקציית
createContactמהשיעורים הקודמים, אשר:- מקצה באופן דינמי זיכרון למבנה מסוג
Contact - מאתחלת את כל השדות לערכי ברירת מחדל
- מחזירה מצביע לאיש הקשר
- מקצה באופן דינמי זיכרון למבנה מסוג
- לכתוב פונקציית
populateContactאשר:- מקבלת כפרמטר מצביע למבנה מסוג
Contact - משתמשת ב-
fgets()כדי לקרוא כל שדה מחרוזת (שם, טלפון, דוא"ל), כך שאפשר יהיה להזין שמות הכוללים רווחים - משתמשת ב-
strcspn()כדי להסיר את תו ירידת השורה שבסוף כל שדה מחרוזת לאחר קריאתו - משתמשת ב-
scanf("%d", ...)כדי לקרוא את שדה הגיל, שהוא מספר שלם - הערה: גרסה זו של
populateContactאינה כוללת בדיקת אורך של מספר הטלפון: אל תוסיף אותה, כי הקלטים בבדיקות משתמשים במספרי טלפון קצרים כמו555-1234
- מקבלת כפרמטר מצביע למבנה מסוג
- לכתוב פונקציה בשם
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
- אם הגיל בין 0 ל-12:
- בודקת אם כתובת הדוא"ל מכילה את התו
'@'באמצעותstrchr()ומדפיסה:- אם התו
'@'נמצא:Email format: Valid - אם התו
'@'לא נמצא:Email format: Invalid
- אם התו
- מחשבת את אורך השם באמצעות
- מקבלת כפרמטר מצביע קבוע למבנה מסוג
- בפונקציה הראשית:
- יוצרים איש קשר באמצעות הפונקציה
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;
}כל השיעורים ביחידה לוגיקה וזרימת תוכנית
1יסודות המצביעים
מהו מצביע?הכרזה על מצביעיםאופרטור לקיחת הכתובת (&)אופרטור ביטול ההפניה (*)מצביעי NULLסיכום: יסודות המצביעים2מצביעים ומערכים
שמות מערכים כמצביעיםאיברי מערך ומצביעיםאריתמטיקה של מצביעיםהשוואת מצביעיםסיכום: מעבר על מערך באמצעות מצביעים5מצביעים ופונקציות
העברה לפי ערךהעברת מצביעים לפונקציותשינוי משתנים באמצעות מצביעיםדוגמה קלאסית: החלפההעברת מערכים לפונקציותחזרה: ארגומנטים של מצביעי פונקציה3מערכי תווים ומחרוזות
מחרוזות כמערכי charתו הסיום nullקלט מחרוזת באמצעות scanfשימוש ב־strlen()שימוש ב־strcpy()שימוש ב־strcat()שימוש ב־strcmp()סיכום: פונקציות מחרוזת בסיסיות6ניהול זיכרון
זיכרון מחסנית לעומת ערימההקצאה דינמית - malloc()שימוש ב-sizeof() להקצאהבדיקת כישלון בהקצאהשחרור זיכרון באמצעות free()הקצאה באמצעות calloc()סיכום: מערך דינמי9פרויקט: רישום איש קשר פשוט
פרויקט: הגדרת מבנה איש קשרפונקציה ליצירת איש קשרתרגלו בעצמכם: קומפיילר C אונליין