第11回演習:解答例


(1)【構造体】5件の名前,出身地,誕生日のデータファイル(右クリック-->[対象をファイルに保存] )data.txtがある.
このファイルは,名前 出身地 年齢 西暦 月 日の順にデータが並んでいる.
①構造体を用いて,このファイルを読み込んで画面に出力しなさい.
②現在の日付を入力すると,年齢を計算し,データの3列目に代入しなさい.(年齢の初期値は0となっている.)
③年齢が上書きされたデータを[result.csv]というファイルに書き出しなさい.


#include <stdio.h>

struct data {
    char name[25];
    char home[25];
    int age;
    int year;
    int month;
    int day;
    
};

void read(struct data *p, int n)
{
	int i;
	
	FILE *fp;
	
	fp = fopen("data.txt","r");
	if(fp == NULL){
		printf("ファイルがありませんでしたorz¥n");
		return;
	}
	
	for(i=0;i<n;i++){
		fscanf(fp, "%s", (*(p+i)).name);
		fscanf(fp, "%s", (*(p+i)).home);
		fscanf(fp, "%d", &(*(p+i)).age);
		fscanf(fp, "%d", &(*(p+i)).year);
		fscanf(fp, "%d", &(*(p+i)).month);
		fscanf(fp, "%d", &(*(p+i)).day);
	}
	
	fclose(fp);

}

void disp(struct data *p, int n)
{
	int i;
	
	printf("名前¥t出身地¥t年齢¥t西暦¥t月¥t日¥n");
	for(i=0;i<n;i++){
		printf("%s¥t%s¥t%d¥t%d¥t%d¥t%d¥n",(*(p+i)).name,(*(p+i)).home,(*(p+i)).age,(*(p+i)).year,(*(p+i)).month,(*(p+i)).day);
	}
	printf("¥n");

}

void age_calc(struct data *p, int n)
{
	int i, year, month, day;
	
	printf("西暦:");
	scanf("%d",&year);
	
	printf("月:");
	scanf("%d",&month);
	
	printf("日:");
	scanf("%d",&day);
	
	printf("¥n");
	
	for(i=0;i<n;i++){
		if(month > (*(p+i)).month){
			(*(p+i)).age = year - (*(p+i)).year;
		} else if(month == (*(p+i)).month && day >= (*(p+i)).day){
			(*(p+i)).age = year - (*(p+i)).year;
		} else{
			(*(p+i)).age = year - (*(p+i)).year - 1;
		}
	}

}

void write(struct data *p, int n)
{
	int i;
	
	FILE *fp;
	
	fp = fopen("result.csv","w");
	if(fp == NULL){
		printf("ファイルを作れませんでしたorz¥n");
		return;
	}
	
	fprintf(fp, "名前,出身地,年齢,西暦,月,日¥n");
	for(i=0;i<n;i++){
		fprintf(fp, "%s,%s,%d,%d,%d,%d¥n", (*(p+i)).name,(*(p+i)).home,(*(p+i)).age,(*(p+i)).year,(*(p+i)).month,(*(p+i)).day);
	}
	
	fclose(fp);

}

void main()
{
	struct data list[5];
	
	read(list,5);
	disp(list,5);
	age_calc(list,5);
	disp(list,5);
	write(list,5);
}

(2)【グラフィックス】初速v0=50(m/s),角度θ=45°で放たれた球が,地面に衝突し跳ね返り続ける球の軌跡をグラフィックスを用いて描きなさい.
ただし,はね返り係数e=0.8とし,空気抵抗は無視する.また,斜方投射の式は以下を参照すること
水平方向の距離 x=(v0×cosθ)×t ,鉛直方向の距離 y=(eJ×v0×sinθ)×t-g×t2/2 (t : 時間 ,J : 衝突回数)
グラフィックスを参考に,xとyをプロットすること


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

void graphic(void)
{
	double x, y, v0, rad, e, j, g, t, count;
	
	v0 = 50.0;
	rad = 45.0/180.0*3.141;
	e = 0.8;
	j = 0.0;
	g = 9.81;
	count = 0.0;

	gl_clearbuffer();

	line(-320,0,320,0,10);

	for(t=0;t<100;t+=0.01){
		x = (v0 * cos(rad)) * t - 320;
		y = (pow(e,j) * v0 * sin(rad)) * (t-count) - g * pow(t-count,2)/2;
		
		if(y <= 0 && t > 0){
			j++;
			count = t;
		}
		
		pset(x,y,4);
	}
	
	gl_flush();

}

void main()
{
	gl_int(640, 480);

	gl_displayfunc(graphic);

	gl_loop();
}

(3)【二次元配列】ファイルから4×4の2次元行列Aを読み込み画面に表示するプログラムを,関数を用いて作成せよ.
行列は、次のファイルを(右クリック-->[対象をファイルに保存])で作成したプログラムと同じフォルダに入れること.
   [Amat.txt],


#include <stdio.h>

void read_matrix(char filename[], float mat[4][4])
{
	int i,j;
	FILE* fp;
	
	fp = fopen(filename, "r");
	if(fp == NULL){
		printf("ファイルがありませんでしたorz¥n");
		return;
	}
	
	for(i=0;i<4;i++){
		for(j=0;j<4;j++){
			fscanf(fp, "%f", &mat[i][j]);
		}
	}
	
	fclose(fp);

}

void print_matrix(float mat[4][4])
{
	int i, j;
	
	for(i=0;i<4;i++){
		for(j=0;j<4;j++){
			printf("%.1f¥t", mat[i][j]);
		}
		printf("¥n");
	}

}

void main()
{
	float Amat[4][4];
	char filename1[]="Amat.txt";
	
	read_matrix(filename1,Amat);
	
	print_matrix(Amat);
 
}