第11回:配列とファイル

今週は,「ファイルからデータを配列に読みこむ」,「配列のデータをファイルへ書き込む」ことを学びます.


【第8回 演習1,第9回,第10回】

sin, cos の計算とグラフィック表示,ファイル入出力

(1) まず,システムに用意された三角関数を利用して,値を計算してみよう.システムに用意された数学関数を利用するには,「math.h」を include する必要がある.

#include <stdio.h>
#include <math.h>

void main()
{
    int i;

    for(i=0; i<360; i++){
        printf("%d, %f, %f\n", i, sin(i*3.14/180.0), cos(i*3.14/180.0));
    }
}

(2) これを応用して,sin, cos のグラフを表示してみよう.グラフィックを利用するには,「mogra.f」を include する.各値をうまく画面に見えるように変換し,点を表示します.

#include <stdio.h>
#include <math.h>
#include "mogra.f"

void main()
{
    int x, y;

    g_int(640,480);

    for(x=0; x<640; x++){
        y = 240 - 100 * sin(3.1415*x/320);
        pset(x, y, 9);

        y = 240 - 100 * cos(3.1415*x/320);
        pset(x, y, 10);
    }

    gend();
}

			

(3) 次に,計算結果をファイルに保存してみよう.ファイル名は,最初から決まっているとします.

#include <stdio.h>
#include <math.h>

void main()
{
    int i;
    FILE *fp;

    fp = fopen("sincos.csv", "w");

    for(i=0; i<360; i++){
         printf(    "%d, %f, %f\n", i, sin(i*3.14/180.0), cos(i*3.14/180.0));
        fprintf(fp, "%d, %f, %f\n", i, sin(i*3.14/180.0), cos(i*3.14/180.0));  
    }

    fclose(fp);
}

(4) 保存したファイルからデータを読み込んで,グラフを表示しよう.いきなりグラフでは,うまくいかないときにわかりにくいので,画面にも表示するようにしよう.値はファイルから読めばよいので,数学関数は使いません.

#include <stdio.h>
#include "mogra.f"

void main()
{
    int i, x, y;
    float siny, cosy;
    FILE *fp;

    fp = fopen("sincos.csv", "r");
    g_int(640,480);

    for(i=0; i<360; i++){
        fscanf(fp, "%d, %f, %f", &x, &siny, &cosy);
         printf(    "%d, %f, %f\n", x, siny, cosy);

        y = 240 - 100 * siny;
        pset(x, y, 0);

        y = 240 - 100 * cosy;
        pset(x, y, 0);
    }

    gend();
}

				

先週のプログラムでは,ファイルからデータを一個づつ取り出しました.では,ファイルから10個のデータを一気に読み込んで,画面に表示するにはどうしたら良いでしょう.

データは,配列に読み込みたいですよね.(そんなことはない?)

配列にキーボードからデータを読み込みには,

#include <stdio.h>

void main()
{
    int i, n;
    int data[10];

    for(i = 0; i < 10; i++) {
        printf("%d番目のデータ:", i+1); scanf("%d", &(data[i]));
    }

    for(i=0; i<10; i++) printf("%d\n", data[i]);
}  

でしたね.これをファイルから読み込むように変えてみましょう.

#include <stdio.h>

void main()
{
    int i, n;
    int x[10];
    float siny[10], cosy[10];
    FILE *fp;

    fp = fopen("sincos.csv", "r");

    for(i = 0; i < 10; i++){
        fscanf(fp, "%d, %f, %f", &(x[i]), &(siny[i]), &(cosy[i]));
    }

    fclose(fp);

    for(i=0; i<10; i++) printf("%d, %f, %f\n", x[i], siny[i], cosy[i]);
}  

ここで,事前にデータの個数がわからないとしたら,どうしたらよいだろう?

ファイルの終わりには,文字列と同様おしまいのマーク「EOF」がついています.EOFを探すには,feof()関数を使います.この関数は,ファイルの終わりに達すると,trueになります.

この関数を使って,データの並んだファイルから,配列にデータを読み込んでみよう.配列は,あらかじめ大きめに用意しておきます.

#include <stdio.h>

void main()
{
    int i, n;
    int x[512];
    float siny[512], cosy[512];
    FILE *fp;

    fp = fopen("sincos.csv", "r");

    i = 0;
    do{
        fscanf(fp, "%d, %f, %f", &(x[i]), &(siny[i]), &(cosy[i]));
        i++;
    }while(!(feof(fp)));

    fclose(fp);

    n = i-1;
    for(i=0; i<n; i++) printf("%d, %f, %f\n", x[i], siny[i], cosy[i]);
}  

または,for文を使って,

#include <stdio.h>

void main()
{
    int i, n;
    int x[512];
    float siny[512], cosy[512];
    FILE *fp;

    fp = fopen("sincos.csv", "r");

    for(i = 0; !(feof(fp)); i++)  fscanf(fp, "%d, %f, %f", &(x[i]), &(siny[i]), &(cosy[i]));

    fclose(fp);

    n = i-1; 
    for(i=0; i<n; i++) printf("%d, %f, %f\n", x[i], siny[i], cosy[i]);
}  

【演習】

100人の試験結果のデータ testdata.txt(100点満点で正の整数)を読み込んで,試験の平均値を求めるプログラムを作ろう.

これができた人は,標準偏差を求めてから各点数の偏差値を求めてみよう.

さらに,できた人は,関数の演習で作成した並べ替える関数を使って,成績のよい順に並べ替えて,結果を別のファイルに保存してみよう.