見出し画像

C言語学習3

昨日は体調が悪かったので勉強をサボりました。
Piscineまであまり時間が残っていないので、Piscine中も体調を崩さないよう体調管理もしっかりしていきたいところ。

今日は苦C 16章からはじめ、構造体が出てきました。
前回、16章を読んだ時は全然頭に入ってきませんでしたが、
今日読んだらちゃんと理解することができました。
前回はポインタで体力が尽きていたようです。

練習問題16
3人分の、名前、年齢、性別、を入力して表示するプログラムを作りなさい。

ただし、データは構造体で記憶することとする。

また、データの入力と表示はそれぞれ専用の関数を作って行うこととする。

苦C 16章

回答

#include <stdio.h>
#include <string.h>

typedef struct {
    char name[64];
    int age;
    char sex[16];
} staff;

void inputStaff(staff *data, int count);

void printStaff(staff *data, int count);

int main(void) {
    staff data[3];
    int staffCount = sizeof(data) / sizeof(data[0]);

    inputStaff(data, staffCount);
    printStaff(data, staffCount);

    return 0;
}

void inputStaff(staff *data, int count) {
    for (int i = 0; i < count; i++) {
        printf("スタッフ[%d]の名前を入力: ", i + 1);
        scanf("%s", data[i].name);

        printf("スタッフ[%d]の年齢を入力: ", i + 1);
        scanf("%d", &data[i].age);

        printf("スタッフ[%d]の性別を入力: ", i + 1);
        scanf("%s", data[i].sex);
    }
}

void printStaff(staff *data, int count) {
    for (int i = 0; i < count; i++) {
        printf("スタッフ[%d]\n", i + 1);
        printf("名前: %s\n", data[i].name);
        printf("年齢: %d\n", data[i].age);
        printf("性別: %s\n", data[i].sex);
    }
}

答え

#include <stdio.h>
#include <string.h>

typedef struct
{
    char name[256];
    int age;
    int sex;
} People;

void InputPeople(People *data);
void ShowPeople(People data);

int main(void)
{
    People data[3];
    int i;

    for (i = 0; i < 3; i++)
    {
        InputPeople(&data[i]);
    }

    for (i = 0; i < 3; i++)
    {
        ShowPeople(data[i]);
    }

    return 0;
}

void InputPeople(People *data)
{
    printf("名前:");
    scanf("%s", data->name);
    printf("年齢:");
    scanf("%d", &data->age);
    printf("性別(1-男性、2-女性):");
    scanf("%d", &data->sex);
    printf("\n");
}

void ShowPeople(People data)
{
    char sex[16];

    printf("名前:%s\n", data.name);
    printf("年齢:%d\n", data.age);

    if (data.sex == 1)
    {
        strcpy(sex, "男性");
    }
    else
    {
        strcpy(sex, "女性");
    }

    printf("性別:%s\n", sex);
    printf("\n");
}

chatGPTにアドバイスを聞いてみた。

あなたの解答と問題の答えの両方を見た上で、いくつかのアドバイスを提供します。

### あなたの解答について

あなたの解答は、問題の要件をほとんど満たしています。いくつかの改善点を挙げます。

1. **データの構造**:
- `sex` フィールドを `char[16]` としています。これは性別を文字列で保持する場合に適していますが、性別が限られた選択肢(例えば「男性」または「女性」)の場合、整数型(`int`)や列挙型(`enum`)で表現する方が効率的です。

2. **入力バリデーション**:
- 入力されるデータのバリデーション(例えば、年齢が実際に有効な数値かどうか)を行うことで、プログラムの堅牢性を向上させることができます。

3. **名前と性別の入力**:
- `scanf` を使用する際に、バッファオーバーフローを防ぐために、入力文字数の上限を指定することが重要です(例:`scanf("%63s", data[i].name)`)。

### 問題の答えについて

問題の答えは、`People` 構造体を使用しており、性別を `int` 型で保持しています。これにより、性別の入力を数値で行うことができ、出力時に文字列へ変換しています。これは効率的な方法ですが、性別を文字列で直接扱いたい場合は、あなたの解答のような方法も有効です。

### 総合的なアドバイス

- **データの表現**: 性別をどのように扱うかは、アプリケーションの要件によって異なります。数値で表現する場合は、`int` 型や `enum` 型を使用し、文字列で表現する場合は `char` 配列を使用します。
- **入力のセキュリティ**: `scanf` の使用時には、常に入力の上限を設定してバッファオーバーフローを防ぎます。
- **関数の設計**: 入力と出力の関数は、それぞれの操作に特化しており、これは良い設計です。ただし、エラーハンドリングやバリデーションを追加することで、さらに改善できます。

両方の解答とも問題の要件を満たしており、効果的に構造体を使用しています。プログラミングスキルを向上

させるには、異なるアプローチを試し、それらの長所と短所を理解することが重要です。あなたの解答は良く構成されており、問題の答えとは異なるアプローチをとっている点が特に興味深いです。プログラミングにはしばしば多くの正解があり、異なる要件や状況に応じて最適な解答が変わることを覚えておくと良いでしょう。

GPT-4

やったー、褒められた!
答えと比較して思ったことは、入力用関数と表示用関数にループを入れないでよかったなと。入力用、表示用関数は最低限の機能にして、main関数でループさせればよかったなぁと思いました。
あと今回は前回15章の練習問題での反省を生かし、最初に関数のプロトタイプ宣言をして、main関数の大まかな流れを決めてからコーディングしたのでちゃんと入力用関数、出力用関数を作ることができました。
作ってから分解すると思ってたより手間だし、main関数で大まかな流れを書いてから詳細を別の関数で作っていくとかなりスムーズに作れた。
しばらく構造体、プロトタイプ、メイン、関数の順番で書いていこうと思いました。

chatGPTのアドバイスにある入力データのバリデーションをやることも考えたけど、前回はそれを意識しすぎて疲れたので、今回は主題から逸れないように最低限の機能を書いてみた。でも必須なので今後はバリデーションについても少しずつ書いていこうと思う。


この記事が気に入ったらサポートをしてみませんか?