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.
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ớiscanf, vốn dừng khi gặp khoảng trắng). Hàm lưu đầu vào vàobuffer, đọc tối đasize - 1ký 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'trongstr. Hàm này dùng để xóa ký tự xuống dòng ở cuối dofgetsđể lại:str[strcspn(str, "\n")] = '\0';strchr(str, ch): tìm ký tựchtrongstrvà trả về con trỏ đến vị trí của ký tự đó, hoặcNULLnếu không tìm thấy.
Chương trình của bạn cần:
- Dùng cùng định nghĩa struct
Contactnhư trong các bài học trước, với các thành viên:- Một mảng ký tự
namecó kích thước 50 - Một mảng ký tự
phonecó kích thước 20 - Một mảng ký tự
emailcó kích thước 40 - Một số nguyên
age
- Một mảng ký tự
- Dùng cùng hàm
createContactnhư 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ệ
- Cấp phát bộ nhớ động cho một struct
- Viết hàm
populateContactđể:- Nhận con trỏ đến một struct
Contactlà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 sauEnter age:) - Lưu ý: Phiên bản
populateContactnà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
- Nhận con trỏ đến một struct
- Viết một hàm có tên
displayContactđể:- Nhận một con trỏ hằng đến struct
Contactlà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
- Nếu tuổi từ 0 đến 12:
- 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
- Nếu tìm thấy
- Tính độ dài tên bằng
- Nhận một con trỏ hằng đến struct
- 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
- Tạo thông tin liên hệ bằng hàm
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
1Nền tảng về con trỏ
Con trỏ là gì?Khai báo con trỏToán tử lấy địa chỉ (&)Toán tử giải tham chiếu (*)Con trỏ NULLÔn tập: kiến thức cơ bản về con trỏ4Dự án: Công cụ xử lý văn bản đơn giản
Tổng quan dự ánĐếm ký tự2Con trỏ và mảng
Tên mảng dưới dạng con trỏPhần tử mảng và con trỏPhép toán con trỏSo sánh con trỏÔn tập: duyệt mảng bằng con trỏ5Con trỏ và hàm
Truyền theo giá trịTruyền con trỏ vào hàmSửa đổi biến qua con trỏVí dụ kinh điển: hoán đổiTruyền mảng vào hàmÔn tập: đối số con trỏ hàm3Mảng ký tự và chuỗi
Chuỗi dưới dạng mảng charKý tự kết thúc nullNhập chuỗi bằng scanfDùng strlen()Dùng strcpy()Dùng strcat()Dùng strcmp()Ôn tập: các hàm xử lý chuỗi cơ bản6Quản lý bộ nhớ
Bộ nhớ ngăn xếp và bộ nhớ heapCấp phát động với malloc()Dùng sizeof() để cấp phátKiểm tra lỗi cấp phátGiải phóng bộ nhớ với free()Cấp phát với calloc()Ôn tập: Mảng động9Dự án: Nhập thông tin liên hệ đơn giản
Định nghĩa struct ContactHàm tạo liên hệTự luyện tập: Trình biên dịch C online