連絡先を表示する関数
CoddyのCジャーニー「Logic & Flow」セクションの一部 — レッスン 53/63。
チャレンジ
簡単これまでのレッスンで作成した連絡先管理システムを基に、連絡先情報をフォーマットして表示する関数を作成します。このレッスンでは、新しく3つの文字列関数 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()を使用して各文字列フィールド(name, phone, email)を読み取り、スペースを含む名前を受け入れられるようにします- 読み取り後、
strcspn()を使用して各文字列フィールドから末尾の改行を削除します scanf("%d", ...)を使用して整数の 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;
}