ほぷしぃ

納得C言語!

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

演習問題X 第4問の解答


4 データ読込機能の追加

解答プログラム

#include <stdio.h>
#include <stdlib.h>    //exit()で使用

//構造体の型宣言
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);
void file_out(struct student *p);
void file_in(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:データ入力\n3:ファイルに書き出し\n4:ファイルの読み込み\n0:終了\n>>");
        scanf("%d",&sw);

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

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

            //データをファイルへ出力
            case 3:
                file_out(p);
                break;

            //データをファイルから入力
            case 4:
                file_in(p);
                break;

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

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

  :
省略
  :

/******************************/
/* void file_in()             */
/* ファイルからデータ読出     */
/* 引数1:構造体へのポインタ */
/* 戻り値:なし               */
/******************************/
void file_in(struct student *p){
    //ファイル構造体へのポインタ
    FILE *fp;
    char str[256];
    int i=0;

    //読み込みモードでファイルを開
    //開けなかったらエラーを表示し終了
    if(!(fp=fopen("成績表.txt","r"))){
        printf("ファイルオープンエラー!!\n");
        exit(1);
    }

    //fscanfで1行ずつ読み込んで構造体に格納していく
    //ファイルの終わり(EOF)に達したらwhileから抜ける
    while((fscanf(fp,"%d %s %d %s %d %d %d %d %d",
            &(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))!=EOF){
        i++;
    }

    //ファイルを閉じる
    fclose(fp);

    printf("ファイル保存完了\n\n");
}


解説

こちらも(3)同様その他の自作関数を省略します。
ファイルからの読み込み時も同様にファイル構造体へのポインタを宣言し、今度は読み込みモードでファイルを開きます。
whileで1行ずつ読み込んで、それを構造体に格納していきます。
そしてファイルの終端に達したらwhileから抜けます。
fscanfはこのように一度にいくつかのデータを読み出すことができます。
scanfも同様で今までは1つのデータしか入力してきませんでしたが、いくつかのデータを読み込むこともできます。
最後にファイルを閉じるのを忘れないでくださいね。


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