You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

255 lines
7.0 KiB

11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
  1. #include "userinput.h"
  2. #include "fakeinput.h"
  3. #include <ctype.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <math.h>
  8. #include <stdbool.h>
  9. #include <limits.h>
  10. #include <float.h>
  11. char **fakeInput = NULL;
  12. #define LD(name)\
  13. long double name##ldvalue;\
  14. long double *name##ld = NULL;\
  15. if (name != NULL) {\
  16. name##ldvalue = *name;\
  17. name##ld = &name##ldvalue;\
  18. }
  19. void printText(char *text) {
  20. if (fakeInput == NULL) {
  21. printf("%s", text);
  22. fflush(stdout);
  23. }
  24. }
  25. void printlf(long double value) {
  26. if (fakeInput != NULL) {
  27. return;
  28. }
  29. if (roundl(value) == value) {
  30. printf("%.0Lf", value);
  31. }
  32. else {
  33. printf("%Lf", value);
  34. }
  35. }
  36. void trimLeft(char *input) {
  37. size_t length = strlen(input);
  38. int firstIndex = 0;
  39. while (firstIndex < length && isspace(input[firstIndex])) {
  40. firstIndex++;
  41. }
  42. for (int i = 0; i <= length - firstIndex; i++) {
  43. input[i] = input[firstIndex + i];
  44. }
  45. }
  46. void trimRight(char *input) {
  47. size_t length = strlen(input);
  48. int index = length - 1;
  49. while (index >= 0 && isspace(input[index])) {
  50. input[index] = '\0';
  51. index--;
  52. }
  53. }
  54. void trim(char *input) {
  55. trimLeft(input);
  56. trimRight(input);
  57. }
  58. char *readInput() {
  59. if (fakeInput != NULL) {
  60. if (fakeInput[0] == NULL) {
  61. printText("The given list of inputs in the test was exceeded!\n");
  62. exit(1);
  63. }
  64. char *result = malloc(strlen(fakeInput[0])*sizeof(char) + 1);
  65. strcpy(result, fakeInput[0]);
  66. fakeInput = fakeInput + 1;
  67. return result;
  68. }
  69. size_t bufferSize = 100;
  70. char *buffer = malloc(bufferSize*sizeof(char));
  71. char c;
  72. int index = 0;
  73. do {
  74. c = fgetc(stdin);
  75. if (!(bufferSize > index)) {
  76. char *newBuffer = malloc(2*bufferSize*sizeof(char));
  77. for (int i = 0; i < bufferSize; i++) {
  78. newBuffer[i] = buffer[i];
  79. }
  80. bufferSize *= 2;
  81. }
  82. buffer[index] = c;
  83. index++;
  84. }
  85. while(c != '\n' && c != EOF);
  86. buffer[index - 1] = '\0';
  87. trim(buffer);
  88. return buffer;
  89. }
  90. char *usergets(char *message, unsigned long *minLength, unsigned long *maxLength) {
  91. printText(message);
  92. char *result = readInput();
  93. while (minLength != NULL && strlen(result) < *minLength || maxLength != NULL && strlen(result) > *maxLength) {
  94. printText("Ungueltige Eingabe! ");
  95. if (minLength != NULL && maxLength == NULL) {
  96. printText("Die Eingabe muss mind. ");
  97. printlf(*minLength);
  98. printText(" Zeichen lang sein.\n");
  99. }
  100. else if (maxLength != NULL && minLength == NULL) {
  101. printText("Die Eingabe darf maximal ");
  102. printlf(*maxLength);
  103. printText(" Zeichen lang sein.\n");
  104. }
  105. else {
  106. printText("Die Eingabe muss ");
  107. printlf(*minLength);
  108. printText(" bis ");
  109. printlf(*maxLength);
  110. printText(" Zeichen lang sein.\n");
  111. }
  112. printText(message);
  113. result = readInput();
  114. }
  115. return result;
  116. }
  117. bool isNumberValid(long double value, long double *min, long double *max, long double *greaterThan, long double *smallerThan, long double leftBorder, long double rightBorder) {
  118. if (min != NULL && value < *min) {
  119. return false;
  120. }
  121. if (max != NULL && value > *max) {
  122. return false;
  123. }
  124. if (greaterThan != NULL && !(value > *greaterThan)) {
  125. return false;
  126. }
  127. if (smallerThan != NULL && !(value < *smallerThan)) {
  128. return false;
  129. }
  130. if (value < leftBorder) {
  131. return false;
  132. }
  133. if (value > rightBorder) {
  134. return false;
  135. }
  136. return true;
  137. }
  138. void printInvalidNumberMessage(long double value, long double *min, long double *max, long double *greaterThan, long double *smallerThan, long double leftBorder, long double rightBorder) {
  139. printText("Ungueltige Eingabe! Fuer die eingegebene Zahl muss gelten:");
  140. if (min != NULL) {
  141. printText(" >=");
  142. printlf(*min);
  143. }
  144. if (max != NULL) {
  145. printText(" <=");
  146. printlf(*max);
  147. }
  148. if (greaterThan != NULL) {
  149. printText(" >");
  150. printlf(*greaterThan);
  151. }
  152. if (smallerThan != NULL) {
  153. printText(" <");
  154. printlf(*smallerThan);
  155. }
  156. if (min == NULL && greaterThan == NULL) {
  157. printText(" >=");
  158. printlf(leftBorder);
  159. }
  160. if (max == NULL && smallerThan == NULL) {
  161. printText(" <=");
  162. printlf(rightBorder);
  163. }
  164. printText("\n");
  165. }
  166. long double getNumber(char *message, long double *min, long double *max, long double *greaterThan, long double *smallerThan, long double leftBorder, long double rightBorder) {
  167. while (true) {
  168. char *input = usergets(message, NULL, NULL);
  169. if (strlen(input) == 0) {
  170. printText("Fehlende Eingabe!\n");
  171. free(input);
  172. continue;
  173. }
  174. char *endptr;
  175. long double number = strtold(input, &endptr);
  176. if (strlen(endptr) > 0) {
  177. printText("Ungueltige Eingabe! Gib eine gueltige Zahl ein.\n");
  178. free(input);
  179. continue;
  180. }
  181. free(input);
  182. if (isNumberValid(number, min, max, greaterThan, smallerThan, leftBorder, rightBorder)) {
  183. return number;
  184. }
  185. printInvalidNumberMessage(number, min, max, greaterThan, smallerThan, leftBorder, rightBorder);
  186. }
  187. }
  188. short usergethd(char *message, short *min, short *max) {
  189. LD(min)
  190. LD(max)
  191. return getNumber(message, minld, maxld, NULL, NULL, SHRT_MIN, SHRT_MAX);
  192. }
  193. int usergetd(char *message, int *min, int *max) {
  194. LD(min)
  195. LD(max)
  196. return getNumber(message, minld, maxld, NULL, NULL, INT_MIN, INT_MAX);
  197. }
  198. long usergetld(char *message, long *min, long *max) {
  199. LD(min)
  200. LD(max)
  201. return getNumber(message, minld, maxld, NULL, NULL, LONG_MIN, LONG_MAX);
  202. }
  203. long long usergetlld(char *message, long long *min, long long *max) {
  204. LD(min)
  205. LD(max)
  206. return getNumber(message, minld, maxld, NULL, NULL, LLONG_MIN, LLONG_MAX);
  207. }
  208. unsigned short usergethu(char *message, unsigned short *min, unsigned short *max) {
  209. LD(min)
  210. LD(max)
  211. return getNumber(message, minld, maxld, NULL, NULL, 0, USHRT_MAX);
  212. }
  213. unsigned int usergetu(char *message, unsigned int *min, unsigned int *max) {
  214. LD(min)
  215. LD(max)
  216. return getNumber(message, minld, maxld, NULL, NULL, 0, UINT_MAX);
  217. }
  218. unsigned long usergetlu(char *message, unsigned long *min, unsigned long *max) {
  219. LD(min)
  220. LD(max)
  221. return getNumber(message, minld, maxld, NULL, NULL, 0, ULONG_MAX);
  222. }
  223. unsigned long long usergetllu(char *message, unsigned long long *min, unsigned long long *max) {
  224. LD(min)
  225. LD(max)
  226. return getNumber(message, minld, maxld, NULL, NULL, 0, ULLONG_MAX);
  227. }
  228. double usergetlf(char *message, double *min, double *max, double *greaterThan, double *smallerThan) {
  229. LD(min)
  230. LD(max)
  231. LD(greaterThan)
  232. LD(smallerThan)
  233. return getNumber(message, minld, maxld, greaterThanld, smallerThanld, -DBL_MAX, DBL_MAX);
  234. }