A問題(50点)
my_record を宣言し、
main 関数中で、my_record 型構造体変数 data を定義する(外部変数にしないこと)。data のメンバーに入力値を格納し、
変数 data のメンバーの内容を下記実行例のように出力するプログラムを作成せよ。
/* 個人レコード */
struct my_record{
char name[2][20]; /* 氏名(要素0: 姓, 要素1: 名) */
char gender[7]; /* 性別 */
char country[20]; /* 国籍 */
int birthday[3]; /* 生年月日(要素0: 西暦, 要素1: 月, 要素2: 日) */
};
struct my_record data; /* この1行は main関数に書いて外部変数にはしないこと */
実行例
% ./a.out データを入力して下さい 姓 (苗字) -> Smith 名 (名前) -> Olivia 性別 (Male/Female) -> Female 国籍 -> Canada 生まれた年 (西暦) -> 1988 生まれた月 -> 2 生まれた日 -> 24 氏名: Smith Olivia 性別: Female 国籍: Canada 生年月日: 1988/2/24 %
my_record 宣言部分を typedef を利用して、
以下のように書き直したものを prog01.h として保存する。prog01a.c を、 prog01.h を使用した形に書き換えた
prog01b.c を作成せよ。
/* 個人レコード */
typedef struct {
char name[2][20]; /* 氏名(要素0: 姓, 要素1: 名) */
char gender[7]; /* 性別 */
char country[20]; /* 国籍 */
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回ずつ呼ぶcalc_age(My_record) を 追加してmainから呼び出すこと。
int calc_age(My_record) : 年齢基準日との差によって年齢をを求める。
ただし年齢基準日は2026年10月29日とし、年、月、日のそれぞれをマクロで与えるものとする。% ./a.out --------データ入力-------- 姓 (苗字) -> Johnson 名 (名前) -> Liam 性別 (Male/Female) -> Male 国籍 -> Australia 生まれた年 (西暦) -> 1995 生まれた月 -> 5 生まれた日 -> 4 --------データ出力-------- 年齢基準日: 2026/10/29 氏名: Johnson Liam 性別: Male 国籍: Australia 生年月日: 1995/5/4 年齢: 31 %
prog02a.c をさらに変更し、
以下に示すファイルmember.txtをリダイレクションで構造体配列に読み込み、
実行例のように入力されたデータと基準日時点の満年齢を計算し表示しなさい。cp /home/course/prog1/public_html/2026/ex/ex07/member.txt .で、
カレントディレクトリにファイルmember.txtをコピーすることができる)
Brown Noah Male USA 2000 3 31 Jones Ava Female Canada 1999 4 1 Garcia Charlotte Female Spain 1999 7 4 Miller Sophia Female UK 2000 10 2 Davis Elijah Male Australia 1999 5 5 Rodriguez William Male Mexico 2001 12 1 Martinez Amelia Female France 2001 2 4 Hernandez Isabella Female Italy 2001 9 30 Lopez Lucas Male Germany 1999 10 22 Gonzalez Henry Male Brazil 1997 1 24
条件およびプログラム作成のヒント
#define N 20 で与える。input()の入力をうながす printf を削除する。EOF で検出するが、
入力終了を input()関数からmain()側に伝える必要がある。input()関数で入力終了時には
戻り値構造体のメンバー変数birthdayの最初の要素に -1 を入れるものとする。main側では戻り値のbirthdayの最初の要素の値を調べ、-1 なら入力処理を止めればよい。calc_age()はoutput()から呼ぶように変更する。また,以下のプログラム実行例を参考に適宜修正する。% ./a.out < member.txt --------データ出力-------- 年齢基準日: 2026/10/29 氏名: Brown Noah , 性別: Male , 国籍: USA , 生年月日: 2000/ 3/31, 年齢: 26 氏名: Jones Ava , 性別: Female, 国籍: Canada , 生年月日: 1999/ 4/ 1, 年齢: 27 氏名: Garcia Charlotte , 性別: Female, 国籍: Spain , 生年月日: 1999/ 7/ 4, 年齢: 27 氏名: Miller Sophia , 性別: Female, 国籍: UK , 生年月日: 2000/10/ 2, 年齢: 26 氏名: Davis Elijah , 性別: Male , 国籍: Australia , 生年月日: 1999/ 5/ 5, 年齢: 27 氏名: Rodriguez William , 性別: Male , 国籍: Mexico , 生年月日: 2001/12/ 1, 年齢: 24 氏名: Martinez Amelia , 性別: Female, 国籍: France , 生年月日: 2001/ 2/ 4, 年齢: 25 氏名: Hernandez Isabella , 性別: Female, 国籍: Italy , 生年月日: 2001/ 9/30, 年齢: 25 氏名: Lopez Lucas , 性別: Male , 国籍: Germany , 生年月日: 1999/10/22, 年齢: 27 氏名: Gonzalez Henry , 性別: Male , 国籍: Brazil , 生年月日: 1997/ 1/24, 年齢: 29 %
前準備として、データ一行につき「学籍番号、名前、5教科の試験の得点」が書かれている成績ファイル score.txtを自分のディレクトリにコピーしておく。
(端末上で、コマンド cp /home/course/prog1/public_html/2026/ex/ex07/score.txt .で、
カレントディレクトリにファイルscore.txtをコピーすることができる)
79206001 Oliver 96 88 92 85 90 79206002 Emma 72 81 69 88 77 79206003 James 55 63 58 61 66 (中略) 79206014 Grace 84 73 79 68 81 79206015 Leo 31 38 42 35 39 79206016 Chloe 91 94 89 96 93
以下の説明文を読み、題意を満たすプログラムを作成せよ。
(提出ファイル名 prog03.c)
SUBJECT_NUM を使用して、
データを格納する構造体の宣言は typedef によって以下のように行う。
(ヘッダファイルとして独立させてはいけない)
#define SUBJECT_NUM 5 /* 科目数 */
typedef struct{
char id[10]; /* 学籍番号 */
char name[10]; /* 名前 */
int score[SUBJECT_NUM]; /* 各点数 */
int sum; /* 合計点 */
double avg; /* 平均 */
char grade; /* 判定 */
}Record;
sum に、
そして、平均点を要素 avg に代入する。
さらに、平均点に対して会津大学の判定基準でA~D、およびFの判定を行い要素grade に代入する。strcmp関数を使ってよい
(最初にstring.hをインクルードしておくこと)。実行例: % ./a.out score.txt 79206001 Oliver 96 88 92 85 90 451 90.2 A 79206002 Emma 72 81 69 88 77 387 77.4 B 79206003 James 55 63 58 61 66 303 60.6 C 79206004 Sophie 81 76 84 72 79 392 78.4 B 79206005 Daniel 64 69 71 66 73 343 68.6 B 79206006 Lily 89 78 82 74 86 409 81.8 A 79206007 Henry 48 57 62 51 59 277 55.4 C 79206008 Zoe 76 83 79 91 87 416 83.2 A 79206009 Jack 94 97 90 92 95 468 93.6 A 79206010 Emily 42 38 35 47 40 202 40.4 D 79206011 Samuel 68 74 81 77 72 372 74.4 B 79206012 Aria 45 49 44 46 48 232 46.4 D 79206013 Oscar 79 71 75 69 73 367 73.4 B 79206014 Grace 84 73 79 68 81 385 77.0 B 79206015 Leo 31 38 42 35 39 185 37.0 F 79206016 Chloe 91 94 89 96 93 463 92.6 A Input a student name/ID: Henry 79206007 Henry 48 57 62 51 59 277 55.4 C Input a student name/ID: Rosemary This student does not exist! Input a student name/ID: 79206001 79206001 Oliver 96 88 92 85 90 451 90.2 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