第13回 ファイルの復習 (12/17)


第12回演習:解答例


ファイル

大量のデータやバイナリファイルの処理など様々な場面で用いられるファイル操作について,もう一度復習をしましょう.

ファイルの種類

コンピュータのディスク上においては,ファイルはメモリと同様,「0」と「1」の並で表されているが,図のようにファイルには,その性質により大きく分けて二種類あり,それぞれ

テキストファイル
C言語のソースファイルや,ホームページのファイルなど,人間が中身を「文字」として読むことのできるファイル
バイナリファイル
プログラムの実行ファイルや,画像ファイル音楽のファイルなど,人間が「文字」として読めないファイル

と呼ばれている.

これらのデータを効率よく処理することは,解析や計算などでは欠かせない.
次からはファイルの操作をおさらいしよう.

ファイル操作の手順

プログラム中でファイルを扱うときの基本的な流れは

  1. ファイルを開く(オープンと言う).
  2. ファイルから情報を変数に読み込む,またはファイルに変数の内容を書き出す.
  3. ファイルを閉じる(クローズと言う).

である.

ファイル操作プログラム例


#include <stdio.h>

void main()
{
    char filename[100]="test.txt";;    /*  ファイル名のための文字列  */
    FILE *fp;  /*  0:ファイルポインタを宣言  */

    printf("作成するファイル名を入力してください : ");  /*  これは画面への出力  */
    scanf("%s", filename);                       /*  これはキーボードからの入力  */

    fp = fopen(filename, "w");       /*  1:ファイルを開く(オープン)  */

    fprintf(fp, "test ¥n");             /*  2:ファイルに文字列を書き出す  */
    fprintf(fp, "%d ¥n", 10);           /*  2:ファイルに整数を書き出す  */
    fprintf(fp, "%f ¥n"\", 3.1415);       /*  2:ファイルに実数を書き出す  */

    fclose(fp);                      /*  3:ファイルを閉じる開く(クローズ)  */
}

では、中間演習の問題を例に実際のファイル操作を見てみましょう.

あるクラスの生徒20人の身長(実数)が順に並んだファイルsincho.txtがある.

sincho.txt の中身
←1番目の身長
←2番目の身長
←20番目の身長

ファイルから身長を配列に読み込み,クラスの生徒の平均身長を求め,結果を画面に表示するプログラムを,平均身長を求めて戻り値として返す関数を定義して作成せよ.



#include<stdio.h>
float average(float *a,int n)	/*平均身長を求める関数*/
{
	int i;
	float sum=0;
	float heikin;
	
	for(i=0;i<n;i++){
		sum=sum+a[i];
	}

	printf("合計は%fです.¥n",sum);
	
	heikin=sum/n;

	return heikin;
}

void main()
{
	int i,n=0;
	float a[20];	/*人数分の配列を定義する*/
	FILE *fp;	/*0:ファイルポインタの宣言(ファイルを扱う場合には,この宣言は必ず必要!)*/

	fp=fopen("sincho.txt","r");	/*1:ファイルを読み込み専用で開く*/
	if(fp==NULL){		/*1:エラーチェック(sincho.txtが存在しなかったら終了する)*/
		printf("ファイルがありませんでした.¥n");
		return;	/*1:プログラムの強制終了*/
	}
	
	for(i=0;i<20;i++){	/*人数分の繰り返し*/							
		fscanf(fp,"%f",&a[i]);	/*2:ファイルからデータをスキャンし,配列に格納する.*/
		n++;	/*平均身長を求める人数のカウント*/
	}

	printf("平均身長は%fです.¥n",average(a,n));	/*平均身長を求める関数に命令を与え,結果を画面に表示する*/

	fclose(fp);	/*3:ファイルを閉じる(これを忘れると,ファイルが開いたままになる.)*/
}

演習課題

(1) 30件の数字データ30data.txtを読み込み,偶数と奇数に分けてそれぞれ別のファイルに出力せよ.

(2) 文章str1.txtを読み込み,A, B, C,…,z(大文字と小文字を区別)までの各文字が何文字あるかをファイルに書き出すプログラムを作成せよ.
関数を用いて作成すること.

関数:




int count()
{
	・・・
}

void main()
{
	・・・
}


(3) 次の熱電対により得られたデータsokutei.csvを電圧から温度に変換しondo.csvファイルに書き出すプログラムを作成せよ.
ここで測定の時間間隔は0.001[s]でデータ点数は1000,熱電対は,0°から100°の範囲において線形に0Vから5Vまで変化する物とする. 得られた温度データをエクセルにてグラフにしなさい.

(発展問題) 先ほど得られた温度データには,ノイズが乗っている.これをノイズの無い見やすいデータにするには,平滑化やファイルタリングが必要になる.
簡単な平滑化方法には,移動平均法などがある.これはある点の直近データn個を単純に平均する方法である.
今回は前後50点のデータを平均して移動平均を求めよ.前後50点のデータが無いところでは計算をしなくても良いものとする.