以下に4つの実験課題の実装内容を示します。
実験4:図書情報のソートと売上集計
図書情報を保持する構造体配列を用い、売上部数に基づく降順ソートと売上高の合計計算を行います。
#include <stdio.h>
#include <stdlib.h>
#define NUM_BOOKS 10
typedef struct {
char isbn[20];
char title[80];
char author[80];
double price;
int units_sold;
} Book;
void print_books(Book items[], int count);
void sort_sales_volume(Book items[], int count);
double compute_total_sales(Book items[], int count);
int main() {
Book books[NUM_BOOKS] = {
{"978-7-5327-6082-4", "門将之死", "ロナルド・トン", 42.0, 51},
{"978-7-308-17047-5", "自由と愛の地へ", "雲也退", 49.0, 30},
{"978-7-5404-9344-8", "ロンドンの人々", "クレイグ・テイラー", 68.0, 27},
{"978-7-5447-5246-6", "ソフトウェア・アーティファクトの生命周期", "テッド・ジャン", 35.0, 90},
{"978-7-5722-5475-8", "チップの歴史", "汪波", 74.9, 49},
{"978-7-5133-5750-0", "ホスト・ウォーズ", "ブラック・J・ハリス", 128.0, 42},
{"978-7-2011-4617-1", "世界の果てのカフェ", "ジョン・ストリーキー", 22.5, 44},
{"978-7-5133-5109-6", "你好、エイリアン", "英国未来出版グループ", 118.0, 42},
{"978-7-1155-0509-5", "無限の始まり", "デイヴィッド・ドイッチュ", 37.5, 55},
{"978-7-229-14156-1", "源泉", "ア讷・ランド", 84.0, 59}
};
printf("売上部数順による図書リスト:\n");
sort_sales_volume(books, NUM_BOOKS);
print_books(books, NUM_BOOKS);
printf("\n総売上額: %.2f元\n", compute_total_sales(books, NUM_BOOKS));
return 0;
}
void print_books(Book items[], int count) {
printf("%-20s %-30s %-20s %-12s %-12s\n",
"ISBN", "書名", "著者", "価格", "部数");
for (int i = 0; i < count; ++i) {
printf("%-20s %-30s %-20s %-12.2f %-12d\n",
items[i].isbn, items[i].title, items[i].author,
items[i].price, items[i].units_sold);
}
}
void sort_sales_volume(Book items[], int count) {
for (int boundary = 0; boundary < count - 1; ++boundary) {
for (int i = count - 1; i > boundary; --i) {
if (items[i].units_sold > items[i - 1].units_sold) {
Book temp = items[i];
items[i] = items[i - 1];
items[i - 1] = temp;
}
}
}
}
double compute_total_sales(Book items[], int count) {
double total = 0.0;
for (int i = 0; i < count; ++i) {
total += items[i].price * items[i].units_sold;
}
return total;
}
実験5:日付処理と比較
「年-月-日」形式の入力を受け取り、その日がその年の何日目かを算出。また、2つの日付の大小比較を実施します。
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int year;
int month;
int day;
} Date;
void entry_date(Date *pdate);
int day_number_from_year_start(const Date dt);
int compare_date(const Date first, const Date second);
void print_day_index() {
Date input_date;
for (int i = 0; i < 3; ++i) {
entry_date(&input_date);
int nth = day_number_from_year_start(input_date);
printf("%d-%02d-%02d は今年の第 %d 日目です。\n",
input_date.year, input_date.month, input_date.day, nth);
}
}
void compare_birthdays() {
Date person1, person2;
for (int i = 0; i < 3; ++i) {
entry_date(&person1);
entry_date(&person2);
int res = compare_date(person1, person2);
if (res == 0) printf("2人の年齢は同じです。\n");
else if (res < 0) printf("人物Aのほうが年上です。\n");
else printf("人物Bのほうが年上です。\n");
}
}
int main() {
printf("【テスト1】入力日がその年の何日目かを表示\n");
print_day_index();
printf("\n【テスト2】2人の誕生日比較\n");
compare_birthdays();
return 0;
}
void entry_date(Date *pdate) {
scanf("%d-%d-%d", &pdate->year, &pdate->month, &pdate->day);
}
int day_number_from_year_start(const Date dt) {
int month_days[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int days = 0;
bool is_leap = (dt.year % 4 == 0 && dt.year % 100 != 0) || (dt.year % 400 == 0);
if (is_leap) month_days[2] = 29;
for (int m = 1; m < dt.month; ++m)
days += month_days[m];
days += dt.day;
return days;
}
int compare_date(const Date first, const Date second) {
if (first.year != second.year)
return (first.year < second.year) ? -1 : 1;
if (first.month != second.month)
return (first.month < second.month) ? -1 : 1;
if (first.day != second.day)
return (first.day < second.day) ? -1 : 1;
return 0;
}
実験6:アカウント情報の表示(パスワード隠蔽)
アカウント種別(管理者/教員/学生)ごとの情報を表示する際、パスワード欄を「*」でマスクします。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum AccountType { ADMINISTRATOR, STUDENT, INSTRUCTOR };
typedef struct {
char login_id[20];
char pwd[20];
enum AccountType role;
} Account;
void print_masked_accounts(Account accounts[], int count);
int main() {
Account users[] = {
{"u001", "123456", STUDENT},
{"u002", "abc789", STUDENT},
{"u003", "xyz999", STUDENT},
{"admin1", "MasterKey", ADMINISTRATOR},
{"inst1", "prof2023!", INSTRUCTOR},
{"u004", "9876abc", STUDENT}
};
int num = sizeof(users) / sizeof(Account);
print_masked_accounts(users, num);
return 0;
}
void print_masked_accounts(Account accounts[], int count) {
printf("%-12s%-22s%-10s\n", "ID", "パスワード", "種別");
for (int i = 0; i < count; ++i) {
printf("%-12s", accounts[i].login_id);
int len = strlen(accounts[i].pwd);
for (int j = 0; j < len; ++j) putchar('*');
printf("\t");
switch (accounts[i].role) {
case ADMINISTRATOR: puts("管理者"); break;
case STUDENT: puts("学生"); break;
case INSTRUCTOR: puts("教員"); break;
}
}
}
実験7:連絡先リストの操作と表示
緊急連絡先を設定し、表示時に緊急連絡先を最上位に并び、残りは名前の昇順で表示します。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[20];
char phone[15];
int is_priority; // 1=緊急連絡先
} Contact;
void set_priority(Contact list[], int size, const char target[]);
void display_sorted_contacts(Contact list[], int size);
void print_all_contacts(Contact list[], int size);
int main() {
Contact contacts[10] = {
{"Li1", "13800000001", 0},
{"Chen2", "13800000002", 0},
{"Zhang3", "13800000003", 0},
{"Li4", "13800000004", 0},
{"Wang5", "13800000005", 0},
{"Zhao6", "13800000006", 0},
{"Zhou7", "13800000007", 0},
{"Sun8", "13800000008", 0},
{"Wu9", "13800000009", 0},
{"Zheng10", "13800000010", 0}
};
printf("初期 connecet list:\n");
print_all_contacts(contacts, 10);
printf("\n緊急連絡先の設定人数:");
int vip_count;
scanf("%d", &vip_count);
char name_buf[20];
for (int i = 0; i < vip_count; ++i) {
printf("名前を入力(%d/%d):", i + 1, vip_count);
scanf("%19s", name_buf);
set_priority(contacts, 10, name_buf);
}
printf("\n表示(緊急優先+名前昇順):\n");
display_sorted_contacts(contacts, 10);
return 0;
}
void set_priority(Contact list[], int n, const char target[]) {
for (int i = 0; i < n; ++i)
if (strcmp(list[i].name, target) == 0)
list[i].is_priority = 1;
}
void display_sorted_contacts(Contact list[], int n) {
for (int i = 0; i < n - 1; ++i) {
for (int j = 0; j < n - 1 - i; ++j) {
bool should_swap = false;
if (list[j].is_priority < list[j+1].is_priority)
should_swap = true;
else if (list[j].is_priority == list[j+1].is_priority &&
strcmp(list[j].name, list[j+1].name) > 0)
should_swap = true;
if (should_swap) {
Contact tmp = list[j];
list[j] = list[j+1];
list[j+1] = tmp;
}
}
}
for (int i = 0; i < n; ++i) {
printf("%-10s%-14s", list[i].name, list[i].phone);
if (list[i].is_priority)
printf("★");
printf("\n");
}
}
void print_all_contacts(Contact list[], int n) {
for (int i = 0; i < n; ++i) {
printf("%-10s%-14s", list[i].name, list[i].phone);
if (list[i].is_priority) printf("★");
printf("\n");
}
}