#include #include #include #define MAXSTR 10 /* 名前の長さ */ #define MAXENT 10 /* 件数 */ int con_gets2(char* str, int buf_size); void keyflush(int input); int usort2(char** str, int entry); int cmpstr2(char** str1, char** str2); int chgstr2(char** str1, char** str2); /* ----- 滅入ん ----- */ void main() { int i; int entry = 0; char tmp[MAXSTR + 1]; char *list[MAXENT]; char *p; printf("%d 文字以内で氏名を入力してください (%d件)\n", MAXSTR, MAXENT); for (i = 0; i < MAXENT; i++) { if (con_gets2(tmp, MAXSTR + 1) == EOF) { /* 名前の入力を受け付ける */ break; } p = malloc(strlen(tmp) + 1); /* メモリ確保 */ if (p == NULL) { /* 確保できないらしいし */ printf("メモリを確保できません!\n"); return; } strcpy(p, tmp); /* 確保したメモリに文字列を複写 */ *(list + i) = p; /* 確保したメモリのポインタを配列に保存 */ printf("累計件数:%d 件\n", ++entry); } printf("----------\n"); if (usort2(list, entry) == NULL) { /* メモリブロックを指すポインタを入れ替える */ printf("メモリ不足らしい\n"); } for (i = 0; i < entry; i++) { /* 並び替えた内容を表示する */ printf("[%s], [%p]\n", *(list + i), *(list + i)); } for (i = 0; i < entry; i++) { free(*(list + i)); } } /* ----- 関数の定義 ----- */ /* ---- キーボードから文字列を入力 ---- */ /* 行頭で '0' が入力されると EOF を返す */ /* それ以外は 1 を返す */ int con_gets2(char* str, int buf_size) { int cnt = 0; int flag = 1; char ch; while ((ch = getchar()) != '\n') { /* '\n' が出現するまで繰り返し */ if (flag && ch == '0') { /* 行頭で '0' が入力された場合 */ keyflush(ch); return EOF; } else { flag = 0; } if (cnt < buf_size - 1) { /* 改行待ちなんでバッファクリアは考慮していない */ *(str + cnt) = ch; cnt = cnt + 1; } } *(str + cnt) = '\0'; return 1; } void keyflush(int input) { while (input != '\n') { /* 入力バッファのクリア簡易版 */ input = getchar(); } } /* 概要:配列を並べ替える関数 2 (Buble sort) */ /* 引数:char** str 配列のポインタのポインタ, int entry 配列の要素数 */ /* 返値:成功 = 1 (必ず成功する) */ int usort2(char** str, int entry) { int i; char tmp; while (entry > 1) { i = 0; while (i < entry - 1) { /* 件数 - 1 回のループ */ if (cmpstr2(str + i, str + i + 1) == 1) { /* それぞれのメモリブロックの比較 */ if (chgstr2(str + i, str + i + 1) == NULL) { /* A が大きい時にポインタを入れ替える */ return NULL; /* 今回の処理ではエラー発生しないけどお約束でw */ } } i++; /* 桁数をインクリメント */ } entry--; /* 件数をデクリメント */ } return 1; } /* 概要:配列を比較する関数 2 (2 つの配列ブロックの比較) */ /* 引数:char** str1 配列のポインタのポインタ 1, char** str1 配列のポインタのポインタ 2 */ /* 返値:A > B の時 = 1, A == B の時 = 0, A < B の時 = -1 */ int cmpstr2(char** str1, char** str2) { int i; for (i = 0; ;i++) { /* カウンタを進めつつ無限ループ */ if (*(*str1 + i) > *(*str2 + i)) { /* A が大きい */ return 1; } else if (*(*str1 + i) < *(*str2 + i)) { /* B が大きい */ return -1; } if (*(*str1 + i) == '\0' || *(*str2 + i) == '\0') { /* 文字列の終端に達した */ break; } } return 0; /* ここにくるのは同じ文字列なのなのだ */ } /* 概要:配列を入れ替える関数 2 (2 つの配列ブロックの入れ替え) */ /* 引数:char** str1 配列のポインタのポインタ 1, char** str1 配列のポインタのポインタ 2 */ /* 返値:成功 = 1 (必ず成功する) */ int chgstr2(char** str1, char** str2) { char* p; /* ポインタのポインタってのでポインタを入れ替え */ p = *str1; /* バッファに A を退避 */ *str1 = *str2; /* 以下月並み (-_-;) */ *str2 = p; return 1; }