第13回演習:解答例


演習課題

(1)【関数とポインタ】30件の数字データ(右クリック-->[対象をファイルに保存] )30data.txtを読み込み,値を大きい順に並び替え,別のファイル(30data_sorted.txt)に出力せよ


#include <stdio.h>
 
void read(int *data)
{
	int i;
	FILE *fp;
	fp=fopen("30data.txt","r");
	if(fp==NULL){
		printf("ファイルを開くことができません");
		return;
			}
	for(i=0;i<30;i++){
		fscanf(fp,"%d",data+i);
			}
	fclose(fp);
}
 
void sort(int *data)
{
	int i,j,tmp;
	for(i=0;i<30;i++){
		for(j=i;j<30;j++){
			if(*(data+i)<*(data+j)){
				tmp = *(data+i);
				*(data+i) = *(data+j);
				*(data+j) = tmp;
						}
				}
			}
}
 
void write(int *data)
{
	int i;
	FILE *fp;
	
 
	fp=fopen("30data_sorted.txt","w");
	if(fp==NULL){
		printf("ファイルを開くことができません");
		return;
			}
	for(i=0;i<30;i++){
		fprintf(fp,"%d¥n",*(data+i));
			}
	fclose(fp);
}
 
void main()
{
	int data[30];	
 
	read(data);
	sort(data);
	write(data);
}

(2)【構造体】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);
}

(3)【グラフィックス】初速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();
}