fork download
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <conio.h>
  3. #include <ctype.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <time.h>
  8.  
  9. #define WEEK "日 月 火 水 木 金 土"
  10.  
  11. // プロトタイプ宣言
  12. void dispcal(int year, int month);
  13. void subcal(int year, int month, int col);
  14. void strfmt(void* dest, char* fmt, int i);
  15. void normalize(int* pyear, int* pmonth);
  16. int scanym(char* buf, int* pyear, int* pmonth);
  17.  
  18. // グローバル変数
  19. char disp[8][80];
  20.  
  21. int main(int argc, char* argv[])
  22. {
  23. struct tm* ptm;
  24. time_t timer;
  25. char buf[8];
  26. int year;
  27. int month;
  28. int ch;
  29. int flag;
  30. int i;
  31.  
  32. time(&timer);
  33. ptm = localtime(&timer);
  34. year = ptm->tm_year + 1900;
  35. month = ptm->tm_mon + 1;
  36. if (argc == 2) {
  37. scanym(argv[1], &year, &month);
  38. }
  39. while (1) {
  40. dispcal(year, month);
  41. printf("ESCキーで終了\n");
  42. i = 0;
  43. do {
  44. ch = _getch();
  45. flag = 0;
  46. switch (ch) {
  47. case 0x0d: // Enter
  48. buf[i] = '\0';
  49. if (scanym(buf, &year, &month)) {
  50. dispcal(year, month);
  51. printf("年月指定に誤りがあります\n");
  52. _getch();
  53. }
  54. break;
  55. case 0x1b: // ESC
  56. return 0;
  57. case 0x48: // up
  58. month -= 3;
  59. break;
  60. case 0x49: // PageUp
  61. year--;
  62. break;
  63. case 0x4b: // left
  64. month--;
  65. break;
  66. case 0x4d: // right
  67. month++;
  68. break;
  69. case 0x50: // down
  70. month += 3;
  71. break;
  72. case 0x51: // PageDown
  73. year++;
  74. break;
  75. case 0xe0: // 読み飛ばし
  76. default:
  77. flag = 1;
  78. }
  79. if (isdigit(ch) || ch == '/') {
  80. if (i < 7) {
  81. printf("%c", ch);
  82. buf[i++] = ch;
  83. }
  84. }
  85. } while (flag);
  86. normalize(&year, &month);
  87. }
  88. return 0;
  89. }
  90.  
  91. // 3ヶ月分のカレンダーを表示
  92. void dispcal(int year, int month)
  93. {
  94. int i;
  95.  
  96. for (i = 0; i < 8; i++) {
  97. memset(disp[i], ' ', 79);
  98. disp[i][79] = '\0';
  99. }
  100. system("cls");
  101. subcal(year, month - 1, 0);
  102. subcal(year, month, 24);
  103. subcal(year, month + 1, 24 * 2);
  104. for (i = 0; i < 8; i++) {
  105. printf("%s\n", disp[i]);
  106. }
  107. }
  108.  
  109. // 1ヶ月分のカレンダーを作成
  110. void subcal(int year, int month, int col)
  111. {
  112. struct tm tm;
  113. struct tm* ptm;
  114. time_t timer;
  115. int line;
  116. int i;
  117.  
  118. normalize(&year, &month);
  119. strfmt(disp[0] + col, "%d", year);
  120. strfmt(disp[0] + col + 8, "%d月", month);
  121. memcpy(disp[1] + col, WEEK, strlen(WEEK));
  122.  
  123. memset(&tm, 0, sizeof tm);
  124. tm.tm_year = year - 1900;
  125. tm.tm_mon = month - 1;
  126. tm.tm_mday = 1;
  127. timer = mktime(&tm);
  128. line = 2;
  129. for (i = 1; i <= 31; i++) {
  130. ptm = localtime(&timer);
  131. if (ptm->tm_mon != month - 1) {
  132. break;
  133. }
  134. if (ptm->tm_wday == 0 && 1 < i) {
  135. line++;
  136. }
  137. strfmt(disp[line] + col + ptm->tm_wday * 3, "%2d", i);
  138. timer += 24 * 60 * 60;
  139. }
  140. }
  141.  
  142. // 整数を指定書式でメモリにコピー
  143. void strfmt(void* dest, char* fmt, int i)
  144. {
  145. char buf[8];
  146.  
  147. sprintf(buf, fmt, i);
  148. memcpy(dest, buf, strlen(buf));
  149. }
  150.  
  151. // 年月を正常化
  152. void normalize(int* pyear, int* pmonth)
  153. {
  154. if (*pmonth < 1) {
  155. *pyear--;
  156. *pmonth += 12;
  157. }
  158. if (12 < *pmonth) {
  159. *pyear++;
  160. *pmonth -= 12;
  161. }
  162. }
  163.  
  164. // 年月を解釈
  165. int scanym(char* buf, int* pyear, int* pmonth)
  166. {
  167. struct tm* ptm;
  168. time_t timer;
  169. int year;
  170. int month;
  171.  
  172. switch (sscanf(buf, "%d/%d", &year, &month)) {
  173. case 1:
  174. if (year < 100) { // MM
  175. time(&timer);
  176. ptm = localtime(&timer);
  177. month = year;
  178. year = ptm->tm_year + 1900;
  179. } else { // YYYYMM
  180. month = year % 100;
  181. year /= 100;
  182. }
  183. break;
  184. case 2:
  185. if (year < 100) { // YY/MM
  186. year += (year < 75) ? 2000 : 1900;
  187. }
  188. break;
  189. default:
  190. return -1;
  191. }
  192.  
  193. if (year < 1975 || 3000 < year) {
  194. return -1;
  195. }
  196. if (month < 1 || 12 < month) {
  197. return -1;
  198. }
  199. *pyear = year;
  200. *pmonth = month;
  201. return 0;
  202. }
  203.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty