显示联系人的函数
本课属于 Coddy C 学习旅程的“逻辑与流程”单元。第 53 课,共 63 课。
挑战
简单在前几课的联系人管理系统基础上,创建一个函数,以格式化的方式显示联系人信息。本课会介绍你需要用到的三个新字符串函数:fgets()、strcspn() 和 strchr()。下文会先逐一说明这些函数,再列出具体要求。
本课使用的新函数:
fgets(buffer, size, stdin):读取一行输入,包括其中的空格(与遇到空白字符就停止读取的scanf不同)。它会将输入存入buffer,最多读取size - 1个字符。它还会在末尾存入换行符'\n'。strcspn(str, "\n"):返回str中第一个'\n'的索引。它可用于移除fgets留下的末尾换行符:str[strcspn(str, "\n")] = '\0';strchr(str, ch):在str中查找字符ch,并返回指向该字符位置的指针;如果找不到,则返回NULL。
你的程序应该:
- 使用前几课中的相同
Contact结构体定义,包含以下成员:- 大小为 50 的字符数组
name - 大小为 20 的字符数组
phone - 大小为 40 的字符数组
email - 整数
age
- 大小为 50 的字符数组
- 使用前几课中的相同
createContact函数,该函数:- 为
Contact结构体动态分配内存 - 将所有成员初始化为默认值
- 返回指向联系人的指针
- 为
- 编写一个
populateContact函数,该函数:- 接收指向
Contact结构体的指针作为参数 - 使用
fgets()读取每个字符串字段(姓名、电话、电子邮件),以便接受包含空格的姓名 - 读取每个字符串字段后,使用
strcspn()移除末尾的换行符 - 使用
scanf("%d", ...)读取整数年龄字段 - 读取每个字段之前,按原样打印对应提示,提示后不换行:
Enter name:、Enter phone:、Enter email:、Enter age:(这样=== CONTACT DETAILS ===就会紧接在同一行的Enter age:后面) - 注意:此版本的
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
- 如果找到
- 使用
- 接收指向
- 在 main 函数中:
- 使用
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 在线编译器