#include #include #define NINZU 5 typedef struct { char name[11]; int year; int month; int day; unsigned char bitinfo; } CARD; int getdec(int keta, int* ans); int getsex(unsigned char* ans); int getblo(unsigned char* ans); int con_gets(char* str, int buf_size); void keyflush(int input); /* --- 滅入ん --- */ void main () { CARD card[NINZU]; int i, j; int end; char tab[3]; /* 桁揃えのためのオマジナイ */ char eday [] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; /* ダミー, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 */ char sex [][3] = { "男", "女" }; /* 性別 bit を文字で表示用のアレ */ char blood [][5] = { "A", "B", "O", "AB" }; /* 血液型 bit を(以下略) */ for (i = 0; i < NINZU; i++) { /* 人数分の入力を待ち受ける */ printf("***** 名前, 生年月日入力 *****\n"); do { /* 年入力 */ printf("名前入力 %d :", i + 1); /* 名前入力は月並みに */ end = con_gets(card[i].name, 11); if (strlen(card[i].name) > 0) { /* 何がしの記入がある? */ break; } printf("Error! : 匿名は許可されていません\n"); } while (1); if (end == -1) { /* 終了させるべき入力があった? */ break; } do { /* 年入力 */ printf(" 年入力 %d :", i + 1); if (getdec(4, &card[i].year) != -1) { /* 数字以外が入力されてる? */ if (card[i].year >= 1) { /* 紀元前とかはナシにしようや */ break; /* 入力成功 */ } } printf("Error! : 正しい年を入力して下さい\n"); } while (1); do { printf(" 月入力 %d :", i + 1); if (getdec(4, &card[i].month) != -1) { /* 数字以外が入力されてる? */ if (card[i].month >= 1 && card[i].month <= 12) { /* 1 〜 12 の間かね? */ break; /* 入力成功 */ } } printf("Error! : 正しい月を入力して下さい\n"); } while (1); do { printf(" 日入力 %d :", i + 1); if (getdec(4, &card[i].day) != -1) { if (card[i].day >= 1 && card[i].day <= eday[card[i].month]) { /* 月別の末日も考慮してみた */ break; /* 入力成功 */ } } printf("Error! : 正しい日を入力して下さい\n"); } while (1); do { printf("性別入力 %d (1:男 2:女):", i + 1); card[i].bitinfo = 0; /* 初使用前の初期化が必要 */ if (getsex(&card[i].bitinfo) != -1) { /* 性別の入力 */ break; /* 入力成功 */ } printf("Error! : 正しい性別を入力して下さい\n"); } while (1); do { printf("血液型入力 %d (1:A 2:B 3:O 4:AB):", i + 1); if (getblo(&card[i].bitinfo) != -1) { /* 性別の入力 */ break; /* 入力成功 */ } printf("Error! : 正しい血液型を入力して下さい\n"); } while (1); } putchar('\n'); /* 調整 */ if (i > 0) { /* 無入力をチェックしておこう */ printf(" 名 前 \t生 年 月 日\t\t性別\t血液型\n"); /* いわゆるヘッダってやつ */ for (j = 0; j < i; j++) { /* 入力件数分の繰り返し */ tab[0] = '\t'; /* Tab の数を加減して桁あわせ */ tab[1] = '\t'; if (strlen(card[j].name) < 6) { /* 行数表示があるので '6' なのですよ */ tab[2] = '\0'; } else { tab[1] = '\0'; } printf("%d:%s%s%4d年%3d月%3d日\t%s\t%s型\n", j + 1, card[j].name, tab, card[j].year, card[j].month, card[j].day, sex[card[j].bitinfo & 0x01], /* 性別配列の中身を選んで表示 */ blood[(card[j].bitinfo & 0x06) >> 1] /* 血液型配列の(以下略) */ ); } } else { printf("入力がありませんでした\n"); } } int getdec(int keta, int* ans) { int input; /* 1 文字入力の値 */ int sign = 2; /* 最初のループ時:2 整数:0 負数:1 */ int i = 0; /* 繰り返しカウンタ ※ 1 文字読み込んだら増やす */ *ans = 0; /* 文字→数値変換の結果を初期化 */ while ((input = getchar()) != '\n') { i++; /* 繰り返しカウンタを増やす */ if (sign == 2) { /* 符号判定 ※最初の 1 回のみ実行される */ if (input == '-') { /* 負数の時 */ sign = 1; /* 負数フラグ On */ input = getchar(); /* '-' を読み飛ばす */ i++; /* 繰り返しカウンタを増やす */ } else { sign = 0; /* 負数フラグ Off */ } } if (i > keta) { /* 繰り返しの判定 */ break; /* 所定回数に達したら抜ける */ } if (input >= '0' && input <= '9') { *ans = (*ans * 10) + (input - '0'); /* 文字数字を 10 進数に変換 */ } else { keyflush(input); return -1; /* 数字以外の入力ならエラー (-1) */ } } if (sign == 2) { /* 改行だけの入力はエラー */ keyflush(input); return -1; } if (sign) { *ans *= -1; /* 負数の時はそんな感じで */ } keyflush(input); return 0; } int getsex(unsigned char* ans) /* 性別入力 (※ ) */ { int input; *ans = *ans & 0xFE; /* 1111_1110 目的の bit を初期化 */ input = getchar(); if (input == '\n') { return -1; } else if (input >= '1' && input <= '2') { *ans = *ans | ((input & 0x0f) - 1); /* 文字を数値にして目的 bit へ格納 */ } else { keyflush(input); return -1; } input = getchar(); if (input != '\n') { keyflush(input); return -1; } return 0; } int getblo(unsigned char* ans) /* 血液型入力 */ { int input; *ans = *ans & 0xF9; /* 1111_1001 目的の bit を初期化 */ input = getchar(); if (input == '\n') { return -1; } else if (input >= '1' && input <= '4') { *ans = *ans | (((input & 0x0f) - 1) << 1); /* 文字を数値にして目的 bit へ格納 */ } else { keyflush(input); return -1; } input = getchar(); if (input != '\n') { keyflush(input); return -1; } return 0; } int con_gets(char* str, int buf_size) { int atmark = 0; /* 行頭 '@' 出現フラグ 未出現:0 出現:1 */ int cnt = 0; char ch; while ((ch = getchar()) != '\n') { /* '\n' が出現するまで繰り返し */ if (cnt < buf_size - 1) { if (ch == '@') { atmark = 1; /* '@' は要注意! */ } *(str + cnt) = ch; cnt = cnt + 1; } } *(str + cnt) = '\0'; if (atmark == 1 && cnt == 1) { return -1; } return 0; } void keyflush(int input) { while (input != '\n') { /* 入力バッファのクリア簡易版 */ input = getchar(); } }