Łączenie wszystkiego w całość
Część sekcji Logika i sterowanie przepływem ścieżki C w Coddy. Lekcja 54 z 63.
Wyzwanie
ŁatwyUkończ system zarządzania kontaktami, integrując wszystkie funkcje utworzone w poprzednich lekcjach. Twój program powinien:
- Używać tej samej definicji struktury
Contactz poprzednich lekcji, z polami:- Tablicą znaków
nameo rozmiarze 50 - Tablicą znaków
phoneo rozmiarze 20 - Tablicą znaków
emailo rozmiarze 40 - Liczbą całkowitą
age
- Tablicą znaków
- Używać tej samej funkcji
createContactz poprzednich lekcji, która:- Dynamicznie przydziela pamięć dla struktury
Contact - Inicjalizuje wszystkie pola wartościami domyślnymi
- Zwraca wskaźnik do kontaktu
- Dynamicznie przydziela pamięć dla struktury
- Używać tej samej funkcji
populateContactz poprzednich lekcji, która:- Przyjmuje jako parametr wskaźnik do struktury
Contact - Prosi użytkownika o dane i wypełnia wszystkie pola kontaktu
- Sprawdza poprawność wprowadzonych danych
- Przyjmuje jako parametr wskaźnik do struktury
- Napisać funkcję
displayContact, która:- Przyjmuje jako parametr stały wskaźnik do struktury
Contact - Wypisuje każde pole w osobnym wierszu, dokładnie w tym formacie:
Name: John
Phone: 555-1234
Email: john@email.com
Age: 25
- Przyjmuje jako parametr stały wskaźnik do struktury
- Napisać funkcję o nazwie
updateContact, która:- Przyjmuje jako parametr wskaźnik do struktury
Contact - Nic nie zwraca (void)
- Prosi użytkownika o wybranie pola do zaktualizowania, wypisując:
What would you like to update?1. Name2. Phone3. Email4. AgeEnter choice (1-4):
- Odczytuje wybór użytkownika i aktualizuje odpowiednie pole:
- Jeśli wybór wynosi 1: wypisuje
Enter new name:i aktualizuje imię - Jeśli wybór wynosi 2: wypisuje
Enter new phone:i aktualizuje numer telefonu - Jeśli wybór wynosi 3: wypisuje
Enter new email:i aktualizuje adres e-mail - Jeśli wybór wynosi 4: wypisuje
Enter new age:i aktualizuje wiek - Jeśli wybór jest nieprawidłowy (nie należy do zakresu 1–4): wypisuje
Invalid choice
- Jeśli wybór wynosi 1: wypisuje
- Po pomyślnej aktualizacji wypisuje
Contact updated successfully
- Przyjmuje jako parametr wskaźnik do struktury
- W funkcji main zaimplementować kompletny proces zarządzania kontaktem:
- Utworzyć kontakt za pomocą funkcji
createContact - Sprawdzić, czy utworzenie kontaktu się powiodło
- Wywołać funkcję
populateContact, aby wprowadzić początkowe dane kontaktu - Wypisać
--- Initial Contact --- - Wywołać funkcję
displayContact, aby wyświetlić początkowe informacje o kontakcie - Wypisać
--- Updating Contact --- - Wywołać funkcję
updateContact, aby zmienić jedno pole - Wypisać
--- Updated Contact --- - Ponownie wywołać funkcję
displayContact, aby wyświetlić zaktualizowane informacje o kontakcie - Zwolnić dynamicznie przydzieloną pamięć
- Wypisać
Contact management completed
- Utworzyć kontakt za pomocą funkcji
Uwaga: Funkcja displayContact w tej lekcji używa prostego formatu: jeden wiersz na każde pole, bez dodatkowych szczegółów ani jednostek (np. wiek jest wypisywany jako zwykła liczba, a nie "25 years old"). Upewnij się, że wynik dokładnie odpowiada formatowi przedstawionemu powyżej, ponieważ zależą od tego przypadki testowe.
To końcowe wyzwanie łączy wszystkie elementy systemu zarządzania kontaktami: definicję struktury, dynamiczne przydzielanie pamięci, wprowadzanie i sprawdzanie poprawności danych, formatowane wyświetlanie oraz modyfikowanie danych. Zademonstrujesz pełny cykl życia struktury, której pamięć przydzielono dynamicznie — od utworzenia po zwolnienie — ćwicząc jednocześnie organizację funkcji i prawidłowe użycie wskaźników w całym procesie.
Spróbuj swoich sił
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Contact {
char name[50];
char phone[20];
char email[40];
int age;
};
struct Contact* createContact() {
struct Contact* contact = (struct Contact*)malloc(sizeof(struct Contact));
if (contact != NULL) {
strcpy(contact->name, "");
strcpy(contact->phone, "");
strcpy(contact->email, "");
contact->age = 0;
}
return contact;
}
void populateContact(struct Contact* contactPtr) {
printf("Enter name: ");
fgets(contactPtr->name, sizeof(contactPtr->name), stdin);
contactPtr->name[strcspn(contactPtr->name, "\n")] = '\0';
printf("Enter phone: ");
fgets(contactPtr->phone, sizeof(contactPtr->phone), stdin);
contactPtr->phone[strcspn(contactPtr->phone, "\n")] = '\0';
printf("Enter email: ");
fgets(contactPtr->email, sizeof(contactPtr->email), stdin);
contactPtr->email[strcspn(contactPtr->email, "\n")] = '\0';
printf("Enter age: ");
scanf("%d", &contactPtr->age);
}
void displayContact(const struct Contact *contactPtr) {
printf("=== CONTACT DETAILS ===\n");
printf("Name: %s\n", contactPtr->name);
printf("Phone: %s\n", contactPtr->phone);
printf("Email: %s\n", contactPtr->email);
printf("Age: %d years old\n", contactPtr->age);
printf("========================\n");
printf("Name length: %lu characters\n", strlen(contactPtr->name));
if (contactPtr->age >= 0 && contactPtr->age <= 12) {
printf("Generation: Child\n");
} else if (contactPtr->age >= 13 && contactPtr->age <= 19) {
printf("Generation: Teenager\n");
} else if (contactPtr->age >= 20 && contactPtr->age <= 39) {
printf("Generation: Young Adult\n");
} else if (contactPtr->age >= 40 && contactPtr->age <= 59) {
printf("Generation: Middle-aged Adult\n");
} else if (contactPtr->age >= 60) {
printf("Generation: Senior\n");
}
if (strchr(contactPtr->email, '@') != NULL) {
printf("Email format: Valid\n");
} else {
printf("Email format: Invalid\n");
}
}
int main() {
struct Contact* contact = createContact();
if (contact != NULL) {
populateContact(contact);
displayContact(contact);
free(contact);
printf("Program completed successfully\n");
}
return 0;
}Wszystkie lekcje w sekcji Logika i sterowanie przepływem
1Podstawy wskaźników
Czym jest wskaźnik?Deklarowanie wskaźnikówOperator pobrania adresu (&)Operator dereferencji (*)Wskaźniki NULLPodsumowanie: podstawy wskaźników4Projekt: Proste narzędzie tekstowe
Przegląd projektuLiczenie znaków2Wskaźniki i tablice
Nazwy tablic jako wskaźnikiElementy tablic — wskaźnikiArytmetyka wskaźnikówPorównywanie wskaźnikówPodsumowanie: przechodzenie po tablicy za pomocą wskaźników5Wskaźniki i funkcje
Przekazywanie przez wartośćPrzekazywanie wskaźników do funkcjiModyfikowanie zmiennych za pomocą wskaźnikówKlasyczny przykład: zamianaPrzekazywanie tablic do funkcjiPowtórka: argumenty wskaźnikowe funkcji8Struktury i wskaźniki
Wskaźniki do strukturOperator strzałki (->)Przekazywanie struktur przez wartośćPrzekazywanie wskaźników do strukturDynamiczna alokacja strukturPodsumowanie: modyfikowanie struktury — wskaźnik11Końcowe zadania powtórkowe
Powtórka: dynamiczne łączenie ciągów znakówPowtórka: tablica strukturPowtórka: licznik częstotliwości słów3Tablice znaków i ciągi znaków
Ciągi znaków jako tablice charZnak końca ciąguWczytywanie ciągu za pomocą scanfUżywanie strlen()Używanie strcpy()Używanie strcat()Używanie strcmp()Podsumowanie: podstawowe funkcje do obsługi ciągów znaków6Zarządzanie pamięcią
Pamięć stosu a stertyAlokacja dynamiczna — malloc()Użycie sizeof() do alokacjiSprawdzanie niepowodzenia alokacjiZwalnianie pamięci za pomocą free()Alokacja za pomocą calloc()Podsumowanie: tablica dynamiczna9Projekt: Prosty wpis kontaktu
Projekt: Definiowanie struktury kontaktuFunkcja tworząca kontaktPoćwicz samodzielnie: Kompilator C online