#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[16];
int age;
int salary;
} Employee;
typedef struct emp_list_node {
Employee *employee;
struct emp_list_node *next;
} EmpListNode;
static EmpListNode *head = NULL;
static void print_menu(void);
static int do_the_job(int menu);
static void add_employee(void);
static void add_one_employee(int i);
static void add_emp_to_list(Employee *p);
static void promote_emp(void);
static void search_emp_by_name(void);
static void search_emp_by_salary(void);
static void print_all_emp(void);
static void print_emp(Employee *emp);
static Employee *alloc_emp(void);
static void free_emp_list(void);
int main(int argc, char *argv[])
{
int menu = 0;
int ret = -1;
char buf[128] = { '\0', };
for (;;) {
print_menu();
memset(buf, 0, sizeof(buf));
menu = -1;
if (fgets(buf, sizeof(buf), stdin) == NULL) {
printf("終了します。\n");
break;
}
if (sscanf(buf, "%d", &menu) != 1) {
printf("終了します。\n");
break;
}
ret = do_the_job(menu);
if (ret < 0) {
printf("終了します。\n");
break;
}
}
free_emp_list();
return 0;
}
static void print_menu(void)
{
printf("\n");
printf(" **** 社員データベース管理プログラム ****\n");
printf(" 1:社員追加\n");
printf(" 2:昇級\n");
printf(" 3:名前検索\n");
printf(" 4:年俸検索(ある値以上の年俸を表示)\n");
printf(" 5:全社員の表示\n");
printf("\n");
printf(" 9:End\n");
printf("\nSelect a number > ");
return;
}
static int do_the_job(int menu)
{
switch (menu) {
case 1:
add_employee();
break;
case 2:
promote_emp();
break;
case 3:
search_emp_by_name();
break;
case 4:
search_emp_by_salary();
break;
case 5:
print_all_emp();
break;
case 9:
/* 終了 */
return -1;
default:
/* 入力がおかしい */
printf("入力に誤りがあります。\n");
break;
}
return 0;
}
static void add_employee(void)
{
int num = 0;
int i;
char buf[128] = { '\0', };
printf("現在何人社員がいますか?: ");
if (fgets(buf, sizeof(buf), stdin) == NULL) {
printf("社員の追加を中止します。\n");
return;
}
sscanf(buf, "%d", &num);
if (num < 1) {
printf("社員の追加を中止します。\n");
return;
}
for (i = 0; i < num; i++) {
add_one_employee(i);
}
}
static void add_one_employee(int i)
{
Employee *emp = alloc_emp();
int age = 0, salary = 0;
char buf[128] = { '\0', };
printf("\n%d人目の情報を入力して下さい。\n", i + 1);
printf("名前: ");
memset(buf, 0, sizeof(buf));
if (fgets(buf, sizeof(emp->name), stdin) == NULL) {
goto err_handle;
}
if (sscanf(buf, "%s", emp->name) != 1) {
goto err_handle;
}
printf("年齢: ");
memset(buf, 0, sizeof(buf));
if (fgets(buf, sizeof(buf), stdin) == NULL) {
goto err_handle;
}
// @TODO 入力を検証する
if (sscanf(buf, "%d", &age) != 1) {
goto err_handle;
}
printf("年俸: ");
// @TODO 入力を検証する
memset(buf, 0, sizeof(buf));
if (fgets(buf, sizeof(buf), stdin) == NULL) {
goto err_handle;
}
if (sscanf(buf, "%d", &salary) != 1) {
goto err_handle;
}
emp->age = age;
emp->salary = salary;
add_emp_to_list(emp);
return;
err_handle:
printf("入力を中止します。\n");
free(emp);
}
static void add_emp_to_list(Employee *emp)
{
EmpListNode *p = head;
EmpListNode *newnode = NULL;
if ((newnode = malloc(sizeof(EmpListNode))) == NULL) {
fprintf(stderr, "malloc failed\n");
exit(2);
}
newnode->employee = emp;
if (p == NULL) {
/* list is empty */
head = newnode;
return;
}
while (p->next != NULL) {
p = p->next;
}
p->next = newnode;
newnode->next = NULL;
}
static void promote_emp(void)
{
// printf("Promoted\n");
}
static void search_emp_by_name(void)
{
char buf[16] = { '\0', };
char key[16] = { '\0', };
int keylen = -1;
int n = 0;
EmpListNode *p = NULL;
printf("\n検索する名前を入力して下さい: ");
if (fgets(buf, sizeof(buf), stdin) == NULL) {
printf("検索を中止します。");
return;
}
sscanf(buf, "%s", key);
keylen = strnlen(key, sizeof(key));
p = head;
n = 0;
/* 前方一致検索する */
while (p != NULL) {
if (strncmp(key, p->employee->name, keylen) == 0) {
n++;
print_emp(p->employee);
}
p = p->next;
}
printf("%d件見つかりました。\n", n);
}
static void search_emp_by_salary(void)
{
char buf[16] = { '\0', };
int key = 0;
int n = 0;
EmpListNode *p = NULL;
printf("\n検索する年俸を入力して下さい: ");
if (fgets(buf, sizeof(buf), stdin) == NULL) {
printf("検索を中止します。");
return;
}
sscanf(buf, "%d", &key);
p = head;
n = 0;
/* 年俸がkey以上のEmployeeを探す */
while (p != NULL) {
if (p->employee->salary >= key) {
n++;
print_emp(p->employee);
}
p = p->next;
}
printf("%d件見つかりました。\n", n);
}
static void print_all_emp(void)
{
EmpListNode *p = head;
while (p != NULL) {
print_emp(p->employee);
p = p->next;
}
}
static void print_emp(Employee *emp)
{
printf("--------------------\n");
printf("名前: %s\n", emp->name);
printf("年齢: %d\n", emp->age);
printf("年俸: %d\n", emp->salary);
printf("--------------------\n");
}
static Employee *alloc_emp(void)
{
Employee *ret = NULL;
if ((ret = malloc(sizeof(Employee))) == NULL) {
fprintf(stderr, "malloc() failed\n");
exit(1);
}
memset(ret, 0, sizeof(Employee));
return ret;
}
static void free_emp_list(void)
{
EmpListNode *p = head, *pp = NULL;
while (p != NULL) {
pp = p;
p = p->next;
free(pp->employee);
}
}