図書管理・日付処理・アカウント表示・連絡先リスト操作の実装

以下に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");
    }
}

タグ: C struct Enum Sorting strcmp

5月31日 12:31 投稿