ほぷしぃ

納得C言語!

[第18回]演習問題X 第2問の解答

演習問題X 第2問の解答


2 機能別に振り分ける

解答プログラム

#include <stdio.h>

//構造体の型宣言
struct point{
    int ei;
    int koku;
    int suu;
    int ri;
    int sya;
};

struct student{
    int s_no;
    char name[256];
    int s_year;
    char s_class[256];
    struct point s_point;
};

//プロトタイプ宣言の初期化
void show(struct student *p);
void input(struct student *p);

int main(){
    int sw=1;    //switch用変数

    //構造体の宣言
    //ユーザより入力するので大きめの配列を確保する
    struct student school[256];

    //構造体ポインタを宣言し先頭アドレスを代入
    struct student *p;
    p=school;

    printf("************成績表(プロトタイプG)************\n");

    //0が入力されたら終了
    while(sw!=0){

        printf("何がしたいわけ!?\n");
        printf("1:成績表示\n2:データ入力\n0:終了\n>>");
        scanf("%d",&sw);

        //swの値で行動を変化
        switch(sw){
            //成績表表示
            case 1:
                show(p);
                break;

            //データ入力
            case 2:
                input(p);
                break;

            //終了
            case 0:
                printf("入力を終了します\n");
                break;

            //それ以外
            default:
                printf("指定数以外の入力です\n");
                break;
        }
    }
    return 0;
}

/******************************************/
/* void show()                            */
/* 構造体に格納された成績表を表示する     */
/* 引数1:構造体へのポインタ             */
/* 戻り値:なし                           */
/******************************************/
void show(struct student *p){
    int i = 0;
    printf("                  |       点数\n");
    printf("学籍番号     氏名 学年クラス | 英語 国語 数学 理科 社会\n");
    printf("-------------------------------------------------------------------\n");

    //forで回すところは(1)と同じですね
    for(i=0;((p+i)->s_no)!=0;i++){
        printf("%7d  %10s  %d   %s  |  %d  %d  %d  %d  %d \n",
            (p+i)->s_no,(p+i)->name,
            (p+i)->s_year,(p+i)->s_class,
            (p+i)->s_point.ei,
            (p+i)->s_point.koku,
            (p+i)->s_point.suu,
            (p+i)->s_point.ri,
            (p+i)->s_point.sya
            );
    }
}

/*****************************************/
/* void input()                          */
/* 構造体へ生徒のデータを格納            */
/* 引数1:構造体へのポインタ            */
/* 戻り値:なし                          */
/*****************************************/
void input(struct student *p){
    int i = 0;    //ポインタカウント用

    //無限ループを作る
    while(1){
        printf("%d人目の入力\n",i+1);
        printf("学籍番号=");
        scanf("%d",&(p+i)->s_no);

        //学籍番号に0が入力されたら終了
        if(((p+i)->s_no)==0){
            printf("入力を終了します\n");
            break;
        }

        printf("氏名=");
        scanf("%s",(p+i)->name);
        printf("学年=");
        scanf("%d",&(p+i)->s_year);
        printf("クラス=");
        scanf("%d",(p+i)->s_class);
        printf("点数\n\n");
        printf("英語:");
        scanf("%d",&(p+i)->s_point.ei);
        printf("国語:");
        scanf("%d",&(p+i)->s_point.koku);
        printf("数学:");
        scanf("%d",&(p+i)->s_point.suu);
        printf("理科:");
        scanf("%d",&(p+i)->s_point.ri);
        printf("社会:");
        scanf("%d",&(p+i)->s_point.sya);

        //カウントを1足す
        i++;
    }
}

解説

表示部分とデータ入力部分を関数に分けて行います。
関数へは構造体のポインタを渡すことでメモリの消費を抑えることができます。
メニューで分けるにはswitchで振り分けましたね。
show関数は(1)の表示部分を関数にしただけですね。
input関数は0が入力されるまでscanfで読み込み構造体に書き込みます。
ここで&をつけ忘れやすいので注意してください。
構造体の場所はポインタで表していますが、メンバ変数はポインタではないので&をつけています。
また、whileで無限ループを作る場合、iは手動で1足していく必要があります。
これを忘れると同じ場所に上書きしてしまうので注意です。


ヒント ページのトップ 第3問