A問題(50点)
my_record
を宣言し、
main 関数中で、my_record
型構造体変数 data
を定義する(外部変数にしないこと)。data
のメンバーに入力値を格納し、
変数 data
のメンバーの内容を下記実行例のように出力するプログラムを作成せよ。 /* 個人レコード */ struct my_record{ char lastname[20]; /* 名字 */ char firstname[20]; /* 名前 */ char gender[7]; /* 性別 */ int birthday[3]; /* 生年月日(要素0: 西暦, 要素1: 月, 要素2: 日) */ }; struct my_record data; /* この1行は main関数に書いて外部変数にはしないこと */実行例
% ./a.out データを入力して下さい 名字 -> Smith 名前 -> Olivia 性別 (Male/Female) -> Female 生まれた年 (西暦) -> 1988 生まれた月 -> 2 生まれた日 -> 24 氏名: Smith Olivia 性別: Female 生年月日: 1988/2/24
my_record
宣言部分を typedef
を利用して、
以下のように書き直したものを prog01.h
として保存する。prog01a.c
を、 prog01.h
を使用した形に書き換えた
prog01b.c
を作成せよ。/* 個人レコード */ typedef struct { char lastname[20]; /* 名字 */ char firstname[20]; /* 名前 */ char gender[7]; /* 性別 */ int birthday[3]; /* 生年月日(要素0: 西暦, 要素1: 月, 要素2: 日) */ }My_record;
B問題(50点)
演習問題2(関数の引数・戻り値として構造体を使用する方法を学ぶ)
以下の問題を読み、prog02a.c, prog02b.cの2つのファイルを提出しなさい。prog01b.c
)を
以下の3つの関数に分割した後、実行例のように入力された人の年齢を表示するプログラムを作成せよ。prog01.h
は、そのまま使用すること。
My_record input(void)
: 標準入力(キーボード)から構造体への入力void output(My_record)
: 構造体内容の標準出力への出力(ディスプレイへの表示)int main()
: 構造体変数 data
を定義する。
input
と output
をそれぞれ1回ずつ呼ぶget_age(My_record)
を 追加してmain
から呼び出すこと。
int get_age(My_record)
: 年齢基準日との差によって年齢をを求める。ただし年齢基準日は2024年10月28日とし、年、月、日のそれぞれをマクロで与えるものとする。% ./a.out --------データ入力-------- 名字 -> Johnson 名前 -> Liam 性別 (Male/Female) -> Male 生まれた年 (西暦) -> 1995 生まれた月 -> 5 生まれた日 -> 4 --------データ出力-------- 年齢基準日: 2024/10/28 氏名: Johnson Liam 性別: Male 生年月日: 1995/5/4 年齢: 29
prog02a.c
をさらに変更し、
以下に示すファイルmember.txtをリダイレクションで構造体配列に読み込み、
実行例のように入力されたデータと基準日時点の満年齢を計算し表示しなさい。cp /home/course/prog1/public_html/2024/ex/ex07/member.txt .
で、
カレントディレクトリにファイルmember.txt
をコピーすることができる)
Brown Noah Male 1999 3 31 Jones Ava Female 1998 4 1 Garcia Charlotte Female 1998 7 4 Miller Sophia Female 1999 10 2 Davis Elijah Male 1998 5 5 Rodriguez William Male 2000 12 1 Martinez Amelia Female 2000 2 4 Hernandez Isabella Female 2000 9 30 Lopez Lucas Male 1998 10 22 Gonzalez Henry Male 1996 1 24
条件およびプログラム作成のヒント
#define N 20
で与える。input()
の入力をうながす printf
を削除する。EOF
で検出するが、
入力終了を input()
関数からmain()
側に伝える必要がある。input()
関数で入力終了時には
戻り値構造体のメンバー変数birthday
の最初の要素に -1 を入れるものとする。main
側では戻り値のbirthday
の最初の要素の値を調べ、-1 なら入力処理を止めればよいget_age()
はoutput()
から呼ぶように変更する。また,以下のプログラム実行例を参考に適宜修正する。% ./a.out < member.txt --------データ出力-------- 年齢基準日: 2024/10/28 氏名: Brown Noah , 性別: Male , 生年月日: 1999/ 3/31, 年齢: 25 氏名: Jones Ava , 性別: Female, 生年月日: 1998/ 4/ 1, 年齢: 26 氏名: Garcia Charlotte , 性別: Female, 生年月日: 1998/ 7/ 4, 年齢: 26 氏名: Miller Sophia , 性別: Female, 生年月日: 1999/10/ 2, 年齢: 25 氏名: Davis Elijah , 性別: Male , 生年月日: 1998/ 5/ 5, 年齢: 26 氏名: Rodriguez William , 性別: Male , 生年月日: 2000/12/ 1, 年齢: 23 氏名: Martinez Amelia , 性別: Female, 生年月日: 2000/ 2/ 4, 年齢: 24 氏名: Hernandez Isabella , 性別: Female, 生年月日: 2000/ 9/30, 年齢: 24 氏名: Lopez Lucas , 性別: Male , 生年月日: 1998/10/22, 年齢: 26 氏名: Gonzalez Henry , 性別: Male , 生年月日: 1996/ 1/24, 年齢: 28
前準備として、データ一行につき「学籍番号、名前、5教科の試験の得点」が書かれている成績ファイル score.txtを自分のディレクトリにコピーしておく。
(端末上で、コマンド cp /home/course/prog1/public_html/2024/ex/ex07/score.txt .
で、
カレントディレクトリにファイルscore.txt
をコピーすることができる)
79105001 Alexander 100 100 100 100 100 79105002 Mia 67 77 75 92 80 79105003 Mason 37 60 71 52 75 (中略) 79105014 Ella 81 45 46 75 85 79105015 Sebastian 29 37 40 20 45 79105016 Elizabeth 95 97 90 95 90
以下の説明文を読み、題意を満たすプログラムを作成せよ。
(提出ファイル名 prog03.c)
SUBJECT_NUM
を使用して、
データを格納する構造体の宣言は typedef
によって以下のように行う。
(ヘッダファイルとして独立させてはいけない)#define SUBJECT_NUM 5 /* 科目数 */ typedef struct{ char id[10]; /* 学籍番号 */ char name[10]; /* 名前 */ int score[SUBJECT_NUM]; /* 各点数 */ int sum; /* 合計点 */ double ave; /* 平均 */ char grade; /* 判定 */ }Record;
sum
に、
そして、平均点を要素 ave
に代入する。
さらに、平均点に対して会津大学の判定基準でA~D、およびFの判定を行い要素grade
に代入する。strcmp
関数を使ってよい
(最初にstring.h
をインクルードしておくこと)。実行例: % ./a.out score.txt 79105001 Alexander 100 100 100 100 100 500 100.0 A 79105002 Mia 67 77 75 92 80 391 78.2 B 79105003 Mason 37 60 71 52 75 295 59.0 C 79105004 Evelyn 79 61 82 70 75 367 73.4 B 79105005 Michael 77 60 75 55 60 327 65.4 B 79105006 Harper 88 66 75 45 70 344 68.8 B 79105007 Ethan 43 79 64 18 65 269 53.8 C 79105008 Camila 45 46 75 98 90 354 70.8 B 79105009 Jacob 99 96 95 99 86 475 95.0 A 79105010 Abigail 40 25 37 27 45 174 34.8 F 79105011 Jackson 70 95 96 68 70 399 79.8 B 79105012 Luna 34 58 52 45 55 244 48.8 D 79105013 Levi 99 69 77 60 75 380 76.0 B 79105014 Ella 81 45 46 75 85 332 66.4 B 79105015 Sebastian 29 37 40 20 45 171 34.2 F 79105016 Elizabeth 95 97 90 95 90 467 93.4 A Input a student name/ID: Ethan 79105007 Ethan 43 79 64 18 65 269 53.8 C Input a student name/ID: Rosemary This student does not exist! Input a student name/ID: 79105001 79105001 Alexander 100 100 100 100 100 500 100.0 A Input a student name/ID: Ctrl-D % ./a.out Error! Usage: ./a.out datafilename % ./a.out sample.txt Cannot open data file !
Extra問題
演習問題4(二次元座標情報を格納する構造体を利用したプログラム)
以下の説明文を読み、題意を満たすプログラムを作成せよ。
(提出ファイル名 prog04.c)
display
コマンドを使って表示する。pbm画像の作成については、これまでの演習問題やプログラミング入門のハンドアウト等を参考にせよ。
必要なら数学関数を使用しても良い。使用方法は使用方法はプログラミング入門のハンドアウト等を参照せよ。
その場合、コンパイラのオプションに -lm
を与えること。
(コンパイル例: gcc prog04.c -lm
)
コマンドラインの引数はすべて文字列として得られるが、これを数値(int型) に変換するには、
<stdlib.h>の中の atoi
関数 を使用する。
例えば、文字列変数 str
に文字列 “123” が入っているとき、
atoi(str)
の戻り値は int型の123という値になる。
#include <stdio.h> #include <stdlib.h> /* 数学関数を使いたい場合は以下のコメントを外す */ /* #include <math.h> */ /* マクロ定義 */ #define N 256 /* 画像サイズ */ #define RD 64 /* 円盤の半径 */ #define BLACK '1' #define WHITE '0' /* 構造体宣言 */ typedef struct{ int x; int y; }XYdata; /* 関数のプロトタイプ宣言 */ /* 画像の各ドットを表す外部変数の定義 */ char data[N][N]; int main(int argc, char *argv[]){ XYdata cent; int ncent, i; /* コマンドラインから円の中心座標を何組か入力される */ /* 入力された中心座標が何組あるか計算 */ ncent = ???; /* 画像初期化関数(すべて白くする)をよぶ */ /* 座標の組の数だけ繰り返す */ /* 円の内部を白黒反転する */ circle(cent); /* 表示 */ imgout(); return 0; } /* すべての点を白に初期化する関数 */ void init(void){ } /* 引数で指示された座標の点一つを白黒反転する関数 */ void rev(XYdata a){ } /* 引数で指示された座標を中心に,半径 RD 以内の点を白黒反転する関数 */ void circle(XYdata c){ } /* Plain PBM形式で画像データを出力する関数 */ void imgout(void){ }実行例1: 座標(0, 0)と座標(255, 255)を中心とする円を描く。
% ./a.out 0 0 255 255 | display - &
% ./a.out 128 90 88 160 168 160 | display - &
演習問題5(配列をメンバーに含む構造体の配列を利用したプログラム)
ファイル bus-table-u.txtは、 ある年の会津地区から新宿方面行きの高速バスの時刻情報を格納している。 このファイルの 1 行目には 2 行目以降に入っているデータの説明(停留所名など)が書かれており、 2 行目以降に各バス便の号数、運行会社、喜多方?新宿の停留所の時刻が入っている。 時刻は時・分を合わせた3-4桁の整数(11時50分なら1150)で表示されており、 バスが停車しない停留所には値 -999 が入っている。
このとき,以下の説明文を読み、題意を満たすプログラムを作成せよ。
(提出ファイル名 prog05.c)
main
側で行うとよい)#include <stdio.h> #include <string.h> #include <stdlib.h> #define NMAX 20 /* 1日の最大バス本数 */ #define NSTOP 6 /* バス停留所数 */ #define UNDEF -999 /* バスが停車しない時を表すダミー値 */ typedef struct{ char colstr1[8]; /* カラム1(番号) */ char colstr2[8]; /* カラム2(会社名) */ char bsname[NSTOP][12]; /* バスの停留所名 */ }Tableinfo; typedef struct{ int number; /* バス番号 */ char company[8]; /* 会社名 */ int hour[NSTOP]; /* 時間 */ int min[NSTOP]; /* 分 */ }Businfo; void printInfo(Businfo, Tableinfo); /* 結果表示用関数 */ ...実行例
% ./a.out bus-table-u.txt Input the name of bus stop. Wakamatsu Hours from/to? 7 9 Number: 4 Company: Aizubus Kitakata 6:50 Wakamatsu 7:30 Oji 11:16 Ikebukuro 11:26 Shinjuku 11:50 Number: 6 Company: JRbus Wakamatsu 8:30 Inawashiro 9:00 Oji 12:40 Ikebukuro 12:50 Shinjuku 13:14 Number: 8 Company: Aizubus Wakamatsu 9:30 Oji 13:16 Ikebukuro 13:26 Shinjuku 13:50