baadgeorge

Untitled

Dec 12th, 2020
39
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.47 KB | None | 0 0
  1. #define _CRT_SECURE_NO_DEPRECATE
  2.  
  3. #include <locale.h>
  4. #include <math.h>
  5. #include <stdio.h>
  6. #include <ctype.h>
  7. #include <string.h>
  8.  
  9. #define SIZEMAX 256
  10. #define SIZESTACK 3
  11. #define EXP "2,7182818"
  12. #define PI "3,1415926"
  13.  
  14. // определение структуры для переменных
  15. struct _var
  16. {
  17. char* name; // имя переменной
  18. double value; // значение переменной
  19. };
  20.  
  21. // определение имени variable для типа variable
  22. typedef struct _var var;
  23.  
  24. var** varList = NULL; // двойной указатель на массив переменных
  25. int varCount = 0; // число переменных
  26.  
  27. int createVariable(char* varName)
  28. {
  29. var* newVar = NULL; // указатель на новую переменную
  30.  
  31. varList = realloc(varList, (varCount + 1) * sizeof(var*)); // выделение дополнительной памяти в массиве переменных под новую переменную
  32. if (varList == NULL) // дополнительная память не была выделена
  33. {
  34. return 0;
  35. }
  36.  
  37. newVar = malloc(sizeof(var)); // выделение памяти под новую переменную
  38. if (newVar == NULL) // дополнительная память не была выделена
  39. {
  40. return 0;
  41. }
  42.  
  43. newVar->name = malloc((strlen(varName) + 1) * sizeof(char)); // выделение памяти под имя новой переменной
  44. if (newVar->name == NULL) // память под имя новой переменной не была выделена
  45. {
  46. free(newVar); // очистка памяти под новую переменную
  47. return 0;
  48. }
  49.  
  50. memset(newVar->name, '\0', (strlen(varName) + 1));
  51. memcpy(newVar->name, varName, strlen(varName)); // копирование имени новой переменной в структуру
  52. newVar->value = 0.0; // задание начального значения новой переменной
  53.  
  54. varList[varCount] = newVar; // запись новой переменной в массив переменных
  55.  
  56. varCount++; // увеличение счетчика количества переменных на 1
  57. return 1;
  58. }
  59.  
  60. void clearVariables()
  61. {
  62. int i = 0; // индексная переменная
  63.  
  64. for (i = 0; i < varCount; i++)
  65. {
  66. free(varList[i]->name); // очистка памяти под имя переменной
  67. free(varList[i]); // очистка памяти под значение переменной
  68. }
  69.  
  70. varCount = 0; // обнуление счетчика количества переменных
  71.  
  72. return;
  73. }
  74.  
  75.  
  76. struct _stack
  77. {
  78. double* container;
  79. int size;
  80. };
  81.  
  82. typedef struct _stack stack;
  83.  
  84. stack* stackInit()
  85. {
  86. stack *newStack;
  87. newStack = malloc(sizeof(stack));
  88. if (newStack == NULL)
  89. {
  90. return newStack;
  91. }
  92. newStack->container = NULL;
  93. newStack->size = 0;
  94. return newStack;
  95. }
  96.  
  97. void stackClear(stack** myStack)
  98. {
  99. free((*myStack)->container);
  100. free(*myStack);
  101. return;
  102. }
  103.  
  104. int stackPush(double value, stack** myStack)
  105. {
  106. (*myStack)->size += 1;
  107. (*myStack)->container = realloc((*myStack)->container, sizeof(double) * (*myStack)->size);
  108. if ((*myStack)->container == NULL)
  109. {
  110. return -1;
  111. }
  112. else
  113. {
  114. (*myStack)->container[(*myStack)->size - 1] = value;
  115. return 0;
  116. }
  117. }
  118.  
  119. double stackPop(stack** myStack)
  120. {
  121. double res = 0;
  122. res = (*myStack)->container[(*myStack)->size - 1];
  123. (*myStack)->size -= 1;
  124. (*myStack)->container = realloc((*myStack)->container, sizeof(double) * (*myStack)->size);
  125. return res;
  126. }
  127.  
  128. double operate(char operator, stack** myStack)
  129. {
  130. double op2 = stackPop(myStack);
  131. double op1 = stackPop(myStack);
  132. switch (operator)
  133. {
  134. case '+':
  135. return op1 + op2;
  136. case '-':
  137. return op1 - op2;
  138. case '*':
  139. return op1 * op2;
  140. case '/':
  141. return op1 / op2;
  142. case '^':
  143. return powf(op1, op2);
  144. }
  145. }
  146.  
  147.  
  148. int isOperator(char* str)
  149. {
  150. if (strpbrk(str, "+-/*^") != NULL && strlen(str) == 1)
  151. {
  152. return 1;
  153. }
  154. else
  155. {
  156. return 0;
  157. }
  158. }
  159.  
  160. int isNumber(char* str)
  161. {
  162. int i = 0; // индексная переменная
  163. int foundPoint = 0; // флаг найден ли символ разделитель в вещественном числе
  164.  
  165. // проходим по всем символам лексемы
  166. for (i = 0; i < strlen(str); i++)
  167. {
  168. if (isdigit(str[i]) == 0) // текущий символ не число
  169. {
  170. if (str[i] == ',') // текущий символ - разделитель в вещественном числе
  171. {
  172. if (foundPoint == 0) // символ разделитель ранее не встречен
  173. {
  174. foundPoint = 1; // флаг - символ разделитель найден
  175. }
  176. else
  177. {
  178. return 0;
  179. }
  180. }
  181. else
  182. {
  183. return 0;
  184. }
  185. }
  186. }
  187. return 1;
  188. }
  189.  
  190. int validVarName(char* str)
  191. {
  192. int i = 0; // индексная переменная
  193.  
  194. if (isalpha(str[0]) == 0) // первый символ - не буква
  195. {
  196. return 0;
  197. }
  198.  
  199. // проходим по всем элементам лексемы
  200. for (i = 1; i < strlen(str); i++)
  201. {
  202. if (isalnum(str[i]) == 0) // текущий символ - не буква и не число
  203. {
  204. return 0;
  205. }
  206. }
  207.  
  208. return 1;
  209. }
  210.  
  211. char* calc(char* str);
  212.  
  213. int parVar(char* str)
  214. {
  215. char* tmp = NULL;
  216. int i = 0;
  217. int foundVariable = 0;
  218. int knownVariable = 0;
  219.  
  220. tmp = strtok(str, "\t ");
  221.  
  222. while (tmp != NULL)
  223. {
  224. knownVariable = 0;
  225. if (strcmp(tmp, "EXP") == 0)
  226. {
  227. tmp = strtok(NULL, "\t ");
  228. continue;
  229. }
  230. if (strcmp(tmp, "PI") == 0)
  231. {
  232. tmp = strtok(NULL, "\t ");
  233. continue;
  234. }
  235. if (isNumber(tmp) == 0 && isOperator(tmp) == 0)
  236. {
  237. if (validVarName(tmp) == 1)
  238. {
  239. for (i = 0; i < varCount; i++)
  240. {
  241. if (strcmp(tmp,varList[i]->name) == 0)
  242. {
  243. knownVariable = 1;
  244. break;
  245. }
  246. }
  247. if (knownVariable == 1)
  248. {
  249. tmp = strtok(NULL, "\t ");
  250. continue;
  251. }
  252. if (createVariable(tmp) == 1)
  253. {
  254. foundVariable = 1;
  255. }
  256. }
  257. }
  258. tmp = strtok(NULL, "\t ");
  259. }
  260. return foundVariable;
  261. }
  262.  
  263. int main()
  264. {
  265. int i = 0;
  266. char str[SIZEMAX] = { '\0' };
  267. setlocale(LC_ALL, "RUS");
  268. printf("Введите выражение в обратной польской записи.\n");
  269. printf("Чтобы завершить работу, введите слово ESCAPE.\n\n");
  270.  
  271. printf("ВВОД: ");
  272. gets_s(str, SIZEMAX);
  273.  
  274. char *copyStr = malloc(strlen(str) + 1);
  275. memset(copyStr, '\0', strlen(str) + 1);
  276. strncpy(copyStr, str, strlen(str));
  277.  
  278. if (parVar(copyStr) == 1)
  279. {
  280. for (i = 0; i < varCount; i++)
  281. {
  282. printf("ВЫВОД: Введите значение переменной %s\n\n", varList[i]->name);
  283. printf("ВВОД: ");
  284. scanf("%lf", &varList[i]->value);
  285. }
  286. printf("ВЫВОД: %s\n\n", calc(str));
  287. }
  288. else
  289. {
  290. printf("ВЫВОД: %s\n\n", calc(str));
  291. }
  292.  
  293. clearVariables();
  294. free(copyStr);
  295.  
  296. system("pause");
  297. return 0;
  298. }
  299.  
  300. char* calc(char* str)
  301. {
  302. int strl = strlen(str);
  303. double res = 0;
  304. char* tmp = NULL;
  305. int i = 0;
  306. int foundVariable = 0;
  307. stack *myStack = stackInit();
  308.  
  309. tmp = strtok(str, "\t ");
  310.  
  311. while (tmp != NULL)
  312. {
  313. foundVariable = 0;
  314.  
  315. if (strcmp(tmp, "EXP") == 0) tmp = EXP;
  316. if (strcmp(tmp, "PI") == 0) tmp = PI;
  317.  
  318. if (isNumber(tmp) == 1)
  319. {
  320. stackPush(atof(tmp), &myStack);
  321. }
  322. else if (isOperator(tmp) == 1)
  323. {
  324. if (myStack->size >= 2)
  325. {
  326. stackPush(operate(*tmp, &myStack), &myStack);
  327. }
  328. else
  329. {
  330. stackClear(&myStack);
  331. return "Ошибка! Встречен оператор, а количество чисел в стеке меньше двух.";
  332. }
  333. }
  334. else
  335. {
  336. for (i = 0; i < varCount; i++)
  337. {
  338. // имя переменной в массиве найдено
  339. if (strcmp(tmp, varList[i]->name) == 0)
  340. {
  341. stackPush(varList[i]->value, &myStack);
  342. foundVariable = 1;
  343. }
  344. }
  345. if (foundVariable == 0)
  346. {
  347. stackClear(&myStack);
  348. return "Ошибка! Недопустимое выражение.";
  349. }
  350. }
  351. tmp = strtok(NULL, "\t ");
  352. }
  353. if (myStack->size != 1)
  354. {
  355. stackClear(&myStack);
  356. return "Ошибка! После завершения вычислений в стеке содержится не единственное число.";
  357. }
  358. res = stackPop(&myStack);
  359. stackClear(&myStack);
  360. memset(str, '\0', SIZEMAX);
  361. sprintf(str, "%lf", res);
  362. return str;
  363. }
  364.  
Add Comment
Please, Sign In to add comment