Функция для вывода контакта
Часть раздела Логика и управление потоком путешествия по 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, что и в предыдущих уроках, с полями:- Массив символов
nameразмером 50 - Массив символов
phoneразмером 20 - Массив символов
emailразмером 40 - Целое число
age
- Массив символов
- Использовать ту же функцию
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;
}Все уроки раздела Логика и управление потоком
1Основы указателей
Что такое указатель?Объявление указателейОператор взятия адреса (&)Оператор разыменования (*)Указатели NULLИтоги: Основы указателей4Проект: Простая текстовая утилита
Обзор проектаПодсчет символов2Указатели и массивы
Имена массивов как указателиЭлементы массива — указателиАрифметика указателейСравнение указателейИтоги: Обход массива через указатели5Указатели и функции
Передача по значениюПередача указателей в функцииИзменение переменных через указателиКлассический пример: SwapПередача массивов в функцииИтоги: указатели как аргументы функций8Структуры и указатели
Указатели на структурыОператор «стрелка» (->)Передача структур по значениюПередача указателей на структурыДинамическое выделение памяти для структурИтоги: Изменение структур через указатели11Итоговые задачи на повторение
Повторение: динамическая конкатенация строкПовторение: массив структурПовторение: счетчик частоты слов3Символьные массивы и строки
Строки как массивы charНуль-терминаторВвод строк с помощью scanfИспользование strlen()Использование strcpy()Использование strcat()Использование strcmp()Итоги: основные строковые функции6Управление памятью
Стек против кучиДинамическое выделение — malloc()Использование sizeof() для выделения памятиПроверка ошибок выделения памятиОсвобождение памяти с помощью free()Выделение памяти с помощью calloc()Итоги: Динамический массив9Проект: Простой ввод контактов
Проект: Определение структуры ContactФункция для создания контактаПотренируйтесь самостоятельно: Онлайн-компилятор C