Menu
Coddy logo textTech

פונקציה להצגת איש קשר

חלק מהיחידה לוגיקה וזרימת תוכנית במסלול ה-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 מסוג struct מהשיעורים הקודמים, עם השדות:
    • מערך תווים בשם 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. בפונקציה הראשית:
    • יוצרים איש קשר באמצעות הפונקציה 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 אונליין