Menu
Coddy logo textTech

連絡先を表示する関数

CoddyのCジャーニー「Logic & Flow」セクションの一部 — レッスン 53/63。

challenge icon

チャレンジ

簡単

これまでのレッスンで作成した連絡先管理システムを基に、連絡先情報をフォーマットして表示する関数を作成します。このレッスンでは、新しく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 を返します。

プログラムの要件は以下の通りです:

  1. これまでのレッスンと同じ Contact 構造体の定義を使用します。メンバは以下の通りです:
    • サイズ 50 の文字配列 name
    • サイズ 20 の文字配列 phone
    • サイズ 40 の文字配列 email
    • 整数型の age
  2. これまでのレッスンと同じ createContact 関数を使用します。この関数は:
    • Contact 構造体のメモリを動的に割り当てます
    • すべてのメンバをデフォルト値で初期化します
    • 連絡先へのポインタを返します
  3. 以下の populateContact 関数を記述します:
    • Contact 構造体へのポインタを引数として受け取ります
    • fgets() を使用して各文字列フィールド(name, phone, email)を読み取り、スペースを含む名前を受け入れられるようにします
    • 読み取り後、strcspn() を使用して各文字列フィールドから末尾の改行を削除します
    • scanf("%d", ...) を使用して整数の age フィールドを読み取ります
    • 注意: このバージョンの populateContact には電話番号の長さのバリデーションは含めないでください。テスト入力では 555-1234 のような短い電話番号が使用されるため、追加しないでください。
  4. 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
      • strchr() を使用してメールアドレスに文字 '@' が含まれているか確認し、次のように出力します:
        • '@' が見つかった場合: Email format: Valid
        • '@' が見つからない場合: Email format: Invalid
  5. 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;
}

Logic & Flowのすべてのレッスン