C言語のきほん「ファイルデータの集計(2)」

スポンサーリンク
C言語

先回は、ファイルに保存されている名前、身長、体重のデータを1件ずつ読み込んで、画面に表示し、最後に平均身長と平均体重を表示するプログラムをご紹介した。

今回は、このプログラムを、、ファイルに保存されている名前、身長、体重のデータを1件ずつ読み込んで、身長順にソートした上で、画面に表示し、最後に平均身長と平均体重を表示するプログラムに修正してみよう。

なお、本プログラムは、
 Windows 11 Home(23H2)上で、 Visual Studio Code(1.92.2)を使用して作成し、gcc (Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0で コンパイルしている。

//名前と身長と体重を読み込んで身長順にソートして、平均値を表示するプログラム

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

#define NINZU_MAX   50  //読み込む人数の上限
#define NAME_LEN    100


int main(void)
{
    FILE *fp;

    if((fp = fopen("height-weight.txt","r")) == NULL)
        printf("ファイルをオープンできません\n");
    else {
        int ninzu = 0;                   //人数
        char name[NAME_LEN][NINZU_MAX];  //名前
        double height[NINZU_MAX];        //身長
        double weight[NINZU_MAX];        //体重
        double hsum = 0.0;               //身長の合計
        double wsum = 0.0;               //体重の合計

        for (int i = 0; i < NINZU_MAX; i++)
        {
            if (fscanf(fp,"%s%lf%lf",name[ninzu],&height[ninzu],&weight[ninzu])!= 3)
                break;
            hsum += height[ninzu];
            wsum += weight[ninzu];
            ninzu++;
 
           
        }
        for (int i = 0; i < ninzu -1; i++)      //身長の昇順にバブルソート
        {
            for (int j = ninzu - 1; j > i; j--)
            {
                if (height[j-1] > height[j])
                {
                    char tn[NAME_LEN];
                    double td;
                    strcpy(tn,name[j]);
                    strcpy(name[j],name[j-1]);
                    strcpy(name[j-1],tn);
                    td = height[j]; height[j] = height[j-1]; height[j-1] = td;
                    td = weight[j]; weight[j] = weight[j-1]; weight[j-1] = td;   
   
                }
            }
            
        }
        for (int i = 0; i < ninzu; i++)
            printf("%-10s %5.1f %5.1f\n",name[i],height[i],weight[i]);
        
        printf("-----------------------\n");
        printf("平均       %5.1f %5.1f\n",hsum / ninzu,wsum / ninzu);
        fclose(fp);
        

    }
    return 0;
}

「height-weight.txt」ファイルの内容

Asano	182.0	76.5
Uemura	160.0	59.3
Inoue	162.0	51.6
Murai	170.0	60.7
Tanaka	175.0	83.9
Wada	175.0	72.5

実行結果

Uemura     160.0  59.3
Inoue      162.0  51.6
Murai      170.0  60.7
Tanaka     175.0  83.9
Wada       175.0  72.5
Asano      182.0  76.5
-----------------------
平均       170.7  67.4

本プログラムは、ファイル「height-weight.txt」からの読み取りを行って集計を行う。

実際に読み取りを行っているのが、

fscanf(fp,"%s%lf%lf",name[ninzu],&height[ninzu],&weight[ninzu])

の部分である。
ストリームfpから、1個の文字列と、2個のdouble型実数値を読み取って、それらをname[ninzu]、&height[ninzu]、&weight[ninzu]に格納している。

さて、scanf関数とfscanf関数は、読み取りに成功した項目の個数返却する。

したがって、fscanf関数の返却値が(名前、身長、体重)でなければ、データが読み取れなかった(読み取った項目数が3でなくなったか、あるいは、何らかのエラーが発生してデータが読めなくなった)と判断して、break文によって読み取りを終了する。

for文による繰り返しが終了した後は、身長順にソートを行った上で、身長と体重の平均値を表示し、ファイルをクローズする。

なお、「バブルソート」については、以前、本ブログでも扱っている。

参考)新・解きながら学ぶC言語 第2版  柴田望洋 (監修・著)、 由梨かおる(著)

コメント

タイトルとURLをコピーしました