今回は,前回のファイルの復習と,「ファイルからデータを配列に読み込む」,「配列データをファイルへ書き出す」手順を学ぶ.
前回のプログラムでは,ファイルからデータを一個取り出したり書き込んだりを行いました.
では,ファイルからすべてのデータを配列にすべて読み込んで,その後,画面に表示するにはどうしたら良いか.
配列にキーボードからデータを読み込みには,
#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]);
}
}
のような手順でした.
これをもとに,ファイルから数値を10個,配列に読み込むように改良してみよう.
#include <stdio.h>
void main()
{
int i, n;
float siny[10];
FILE *fp;
fp = fopen("sincos.csv", "r"); /* 読み込みモードでファイルをオープン */
if(fp == NULL) {
printf("ファイルを開くことが出来ませんでした.¥n");
return;
}
for(i=0; i<10; i++){
fscanf(fp, "%f", &(siny[i]) ); /* 1行読む */
}
fclose(fp);
for(i=0; i<10; i++) {
printf("%f¥n", siny[i]);
}
}
ファイルの終わりには,文字列と同様,ファイル終端を表す特殊なマーク「EOF」がついている.(EOFは,End Of File の略)
ファイルを先頭から順に読み込んでゆき,終わりに達したかどうかを判定する(=EOFを探す)には,feof()
関数を使う.
この関数はファイルの終わりに達すると「真」(正確にはゼロでない値)になる.
これを使ってデータの並んだファイルから配列にデータを読み込んでみよう.
配列のサイズは,あらかじめ読み込むデータより大きめに用意しておく.
#include <stdio.h>
void main()
{
int i, n;
float siny[512]; /* 大きめのサイズの配列を用意しておく. */
FILE *fp;
fp = fopen("sincos.csv", "r");
if(fp == NULL) {
printf("ファイルを開くことが出来ませんでした.¥n");
return;
}
n = 0;
/* ファイルが終わりでない 「かつ」 配列を飛び出さないうちは,読み込みを続ける */
while ( ! feof(fp) && n < 512) {
fscanf(fp, "%f", &(siny[n]));
n++;
}
fclose(fp);
n = n-1; /* 上のwhileループでは,EOFの行を余分に読み込んでいるので,実際のデータ数は一つ少ない. */
/* 画面に表示 */
for(i=0; i<n; i++) {
printf("%f¥n", siny[i]);
}
}
(1)試験結果のデータ(右クリック-->[対象をファイルに保存] )testdata.txt(100点満点で正の整数)を読み込んで,
を求めるプログラムを作成せよ.データ数はEOFを元に判断すること.
標準偏差などの求め方は, 前期:配列と繰り返しを参考にすること
(2)更に,平均値,標準偏差から各点数の偏差値を求め,ファイルに保存するプログラムを作成せよ.
(3)ファイルから4×4の2次元行列Aを読み込み画面に表示するプログラムを,以下を参考に関数を用いて作成せよ.
行列は、次のファイルを(右クリック-->[対象をファイルに保存])で作成したプログラムと同じフォルダに入れること.
[Amat.txt],
#include <stdio.h>
/*4×4の行列をファイルから読み込む関数*/
void read_matrix(char filename[], float mat[4][4])
{
int i,j;
FILE* fp;
}
/*4×4の行列を表示する関数*/
void print_matrix(float mat[4][4])
{
}
/*メイン関数*/
void main()
{
float Amat[4][4];
char filename1[]="
";
read_matrix(
,
);
print_matrix(
);
}
(4)ファイルから4×4の2次元行列A,Bを読み込み行列の乗算A・B=Cを行い、計算結果Cをファイルに出力するプログラムを作成せよ.
行列Aと同様にBも保存する.[Bmat.txt],
行列の乗算:
行列B,Cは以下の形になる.
#include <stdio.h>
/*4×4の行列をファイルから読み込む関数*/
void read_matrix(char filename[], float mat[4][4])
{
int i,j;
FILE* fp;
}
/*4×4の行列をファイルに書き出す関数*/
void write_matrix(char filename[], float mat[4][4])
{
int i,j;
FILE* fp;
}
/*4×4の行列を表示する関数*/
void print_matrix(float mat[4][4])
{
}
/*行列の掛け算を行う関数*/
void multi_matrix(float Amat[4][4], float Bmat[4][4], float Cmat[4][4])
{
int i,j,k;
for(
;
;
){
for(
;
;
){
for(
;
;
){
}
}
}
}
/*メイン関数*/
void main()
{
float Amat[4][4], Bmat[4][4], Cmat[4][4];
char filename1[]="
";
char filename2[]="
";
char filename3[]="
";
read_matrix(
,
); /*同じ作業は関数化するほうが使いやすいプログラムになる*/
read_matrix(
,
); /*行列の読み込みプログラムの呼び出し*/
print_matrix(
); /*行列の表示プログラムの呼び出し*/
print_matrix(
);
multi_matrix(
,
,
); /*行列の掛け算プログラムの呼び出し*/
print_matrix(
);
write_matrix(
,
); /*行列の書き込みプログラムの呼び出し*/
}
(5)前回の課題(4)の文字列の長さを計算する関数を用いて、文字列の前後を反転させる関数を作成せよ.
#include <stdio.h>
/*文字の長さを数える関数*/
int moji_nagasa(char str[])
{
}
/*文字を入れ替える関数*/
void moji_irekae(char str[], int n)
{
}
/*メイン関数*/
void main()
{
int n;
char str[128];
printf("文字列を入力してください:");
scanf("%s", str);
printf("入力された文字列は,%sです.", str);
printf("文字数は,%dです.", n = moji_nagasa(str));
moji_irekae(str,n);
printf("入れ替えた文字列は,%sです.", str);
}
授業終了時までのプログラムと完成した提出用プログラムをoh-meijiシステムを使って提出すること.
授業終了時に送るのは出席の確認用であり,完成した課題は提出用の回に送ること.
(提出期限を厳守し,提出用の回に提出しないと採点を行わない)
また提出の行い方については,以下のページを参照してください.
課題の提出方法