Menu
CoddyTech

Hàm hiển thị liên hệ

Thuộc phần Logic và luồng điều khiển trong hành trình C của Coddy. Bài học 53 trên 63.

challenge icon

Thử thách

Dễ

Dựa trên hệ thống quản lý danh bạ bạn đã xây dựng trong các bài học trước, hãy tạo một hàm hiển thị thông tin liên hệ theo định dạng. Bài học này giới thiệu ba hàm chuỗi mới bạn cần dùng: fgets(), strcspn() và strchr(). Mỗi hàm được giải thích bên dưới, trước phần yêu cầu.

Các hàm mới dùng trong bài học này:

  • fgets(buffer, size, stdin): đọc một dòng đầu vào, bao gồm cả dấu cách (khác với scanf, vốn dừng khi gặp khoảng trắng). Hàm lưu đầu vào vào buffer, đọc tối đa size - 1 ký tự. Hàm cũng lưu ký tự xuống dòng '\n' ở cuối.
  • strcspn(str, "\n"): trả về chỉ số của lần xuất hiện đầu tiên của '\n' trong str. Hàm này dùng để xóa ký tự xuống dòng ở cuối do fgets để lại: str[strcspn(str, "\n")] = '\0';
  • strchr(str, ch): tìm ký tự ch trong str và trả về con trỏ đến vị trí của ký tự đó, hoặc NULL nếu không tìm thấy.

Chương trình của bạn cần:

  1. Dùng cùng định nghĩa struct Contact như trong các bài học trước, với các thành viên:
    • Một mảng ký tự name có kích thước 50
    • Một mảng ký tự phone có kích thước 20
    • Một mảng ký tự email có kích thước 40
    • Một số nguyên age
  2. Dùng cùng hàm createContact như trong các bài học trước. Hàm này:
    • Cấp phát bộ nhớ động cho một struct Contact
    • Khởi tạo tất cả thành viên bằng các giá trị mặc định
    • Trả về con trỏ đến thông tin liên hệ
  3. Viết hàm populateContact để:
    • Nhận con trỏ đến một struct Contact làm tham số
    • Dùng fgets() để đọc từng trường chuỗi (name, phone, email) để chấp nhận tên có dấu cách
    • Dùng strcspn() để xóa ký tự xuống dòng ở cuối mỗi trường chuỗi sau khi đọc
    • Dùng scanf("%d", ...) để đọc trường tuổi dạng số nguyên
    • Trước khi đọc từng trường, in chính xác lời nhắc tương ứng, không thêm ký tự xuống dòng sau lời nhắc: Enter name: , Enter phone: , Enter email: , Enter age: (như vậy, === CONTACT DETAILS === sẽ xuất hiện cùng dòng ngay sau Enter age: )
    • Lưu ý: Phiên bản populateContact này không kiểm tra độ dài số điện thoại. Đừng thêm bước kiểm tra này, vì dữ liệu đầu vào của test dùng các số điện thoại ngắn như 555-1234
  4. Viết một hàm có tên displayContact để:
    • Nhận một con trỏ hằng đến struct Contact làm tham số: const struct Contact *contactPtr
    • Không trả về giá trị nào (void)
    • In thông tin liên hệ theo đúng định dạng sau:
      • === CONTACT DETAILS ===
      • Name: [name]
      • Phone: [phone]
      • Email: [email]
      • Age: [age] years old
      • ========================
    • Sau khi hiển thị thông tin cơ bản, tính toán và hiển thị thêm các chi tiết:
      • Tính độ dài tên bằng strlen() và in: Name length: [length] characters
      • Xác định nhóm thế hệ dựa trên tuổi và in:
        • Nếu tuổi từ 0 đến 12: Generation: Child
        • Nếu tuổi từ 13 đến 19: Generation: Teenager
        • Nếu tuổi từ 20 đến 39: Generation: Young Adult
        • Nếu tuổi từ 40 đến 59: Generation: Middle-aged Adult
        • Nếu tuổi từ 60 trở lên: Generation: Senior
      • Dùng strchr() để kiểm tra xem email có chứa ký tự '@' hay không, rồi in:
        • Nếu tìm thấy '@': Email format: Valid
        • Nếu không tìm thấy '@': Email format: Invalid
  5. Trong hàm main:
    • Tạo thông tin liên hệ bằng hàm createContact
    • Kiểm tra xem việc tạo thông tin liên hệ có thành công hay không
    • Gọi hàm populateContact để điền dữ liệu liên hệ
    • Gọi hàm displayContact để hiển thị thông tin liên hệ theo định dạng
    • Giải phóng bộ nhớ đã cấp phát động
    • In Program completed successfully

Thử thách này minh họa cách tạo một hàm hiển thị nhận con trỏ hằng đến một struct, qua đó đảm bảo hàm không thể sửa đổi dữ liệu gốc. Bạn sẽ luyện tập cách dùng fgets() để đọc chuỗi có dấu cách, strcspn() để xóa ký tự xuống dòng ở cuối, toán tử mũi tên để truy cập các thành viên của struct qua con trỏ, strchr() để tìm ký tự và logic điều kiện để phân loại dữ liệu. Dùng const trong khai báo tham số là một thực hành tốt, giúp ngăn việc vô tình sửa đổi dữ liệu liên hệ bên trong hàm hiển thị.

Tự làm thử

#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;
}

Tất cả bài học trong Logic và luồng điều khiển

Tự luyện tập: Trình biên dịch C online