Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Калькулятор поддерживает ввод натуральных чисел (это типо >= 0). Выводит double.
Собственно выкладываю сюда исходник, может кому нужно будет лабу делать.
Собственно выкладываю сюда исходник, может кому нужно будет лабу делать.
Код:
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <conio.h>
#include <string.h>
typedef struct stack_s stack;
char *gets();
stack *CreateStack(int);
stack *AddStack(stack*, int);
double ReadStack(stack*);
stack *DelStack(stack*);
stack *ClearSteck(stack *st);
int ShowMenu();
char *TranslateIntoOPN(char*);
int Priority(char);
double GetResult(char*);
struct stack_s
{
double num;
stack *next;
};
int main()
{
setlocale(LC_ALL, "rus");
stack *st = nullptr;
while (true)
{
system("cls");
ShowMenu();
fflush(stdin);
switch (getch())
{
case '1':
{
printf("Введите выражение: ");
char *str;//Создаем str, чтобы не было утечек памяти
printf("Ответ: %.2f\n", GetResult((str = TranslateIntoOPN(gets()))));//Вводим инфиксное выражение, трансформируем его в постфиксное, считаем
free(str);
getch();
break;
}
case '0': return 0;
}
}
return 0;
}
double GetResult(char *str)//Принимаем постфиксную строку
{
if (!str)
{
puts("\nВ функцию GetResult передана пустая строка, вычисление не выполнено!\a");
return 0;
}
double result;
int i = -1, num = -1;
stack *st = nullptr;
while (str[++i] != '\0')
{
if (str[i] >= '0' && str[i] <= '9')
{
if (num == -1) num = 0;
num = num * 10 + str[i] - 48;
continue;
}
if (num != -1) st = AddStack(st, num);
num = -1;
switch (str[i])
{
case '+':
st->next->num += st->num;
st = DelStack(st);
break;
case '-':
st->next->num -= st->num;
st = DelStack(st);
break;
case '*':
st->next->num *= st->num;
st = DelStack(st);
break;
case '/':
if (!st->num)
{
ClearSteck(st);
puts("\nДеление на 0 невозможно\a");
return 0;
}
st->next->num /= st->num;
st = DelStack(st);
break;
}
}
result = ReadStack(st);
ClearSteck(st);
return result;
}
char *TranslateIntoOPN(char *str)//Переводим из инфиксной нотации в польскую
{
if (!str)
{
puts("\nВ функцию TranslateIntoOPN передана пустая строка, преобразование не выполнено!\a");
return 0;
}
int i = -1, checknum = 0, cur_new_pos = 0;
char *new_str = (char*)malloc(strlen(str) * 2 + 1);// умножаем на 2 для того, чтобы вместились пробелы + 1 на \0
new_str[strlen(str) * 2] = '\0';
stack *st = nullptr;
while (str[++i] != '\0')
{
if (checknum)//Позволяет вводить числа, содержащие более 1 цифры
{
if (new_str[cur_new_pos - 1] != ' ') new_str[cur_new_pos++] = ' ';
checknum = 0;
}
if (str[i] == ' ')
{
free(new_str);
ClearSteck(st);
puts("\nНельзя использовать пробелы!\a");
return 0;
}
else if (str[i] >= '0' && str[i] <= '9')
{
new_str[cur_new_pos++] = str[i];
continue;
}
checknum = 1;
if (str[i] == '(')
{
//Priority можно использовать так же для определения оператора, если > 1, значит это + || - || * || /
if (i && !Priority(str[i - 1]) || str[i + 1] == '\0' || Priority(str[i + 1]) > 1 || str[i + 1] == ')')
{
free(new_str);
ClearSteck(st);
puts("\nОшибка возле '('!\a");
return 0;
}
st = AddStack(st, '(');
continue;
}
else if (str[i] == ')')
{
if (!Priority(str[i + 1]) && str[i + 1] != '\0' || !i || Priority(str[i - 1]) > 1 || str[i - 1] == '(')
{
free(new_str);
ClearSteck(st);
puts("\nОшибка возле ')'!\a");
return 0;
}
char stack_oper;
while (true)
{
if (!st)
{
free(new_str);
puts("\nНесовпадение количества скобок, либо неправильный порядок!\a");
return 0;
}
if ((stack_oper = ReadStack(st)) != '(')
{
if (new_str[cur_new_pos - 1] != ' ') new_str[cur_new_pos++] = ' ';
new_str[cur_new_pos++] = stack_oper;
st = DelStack(st);
continue;
}
st = DelStack(st); //Удаляем нашу скобочку '('
if (new_str[cur_new_pos - 1] != ' ') new_str[cur_new_pos++] = ' ';
break;
}
continue;
}
else if (Priority(str[i]))//Если это оператор + - / *
{
if (!i || Priority(str[i - 1]) > 1 || str[i + 1] == '\0')
{
free(new_str);
ClearSteck(st);
puts("\nНеверная расстановка знаков!\a");
return 0;
}
char stack_oper;
while (true)
{
if (st)
{
if (Priority(str[i]) <= Priority((stack_oper = ReadStack(st))))//Если приоритет текущего оператора <= чем в стеке, извлекаем в ОПН строку
{
if (new_str[cur_new_pos - 1] != ' ') new_str[cur_new_pos++] = ' ';
new_str[cur_new_pos++] = stack_oper;
st = DelStack(st);
continue;
}
}
st = AddStack(st, str[i]);//Помещаем char в поле float, ничего страшного
break;
}
continue;
}
free(new_str);
ClearSteck(st);
puts("\nВ выражении обнаружены лишние символы!\a");
getchar();
return nullptr;
}
while (true)//Дозаписываем операторы из стека в строку
{
if (!st) break;
if (new_str[cur_new_pos - 1] != ' ') new_str[cur_new_pos++] = ' ';
new_str[cur_new_pos++] = ReadStack(st);
if (new_str[cur_new_pos - 1] == '(')
{
ClearSteck(st);
puts("\nНесовпадение количества скобок, либо неправильный порядок!\a");
getchar();
return nullptr;
}
st = DelStack(st);
}
new_str[cur_new_pos] = '\0';
free(str);
return new_str;
}
inline int ShowMenu()
{
printf("First calculator by Dendy\n\n\
Выберете пункт: \n\
\t1 - Ввод строки через консоль\n\
\t0 - Завершение работы\n");
return 0;
}
stack *CreateStack(int num)
{
stack *st = (stack*)malloc(sizeof(stack));
st->next = nullptr;
st->num = num;
return st;
}
stack *AddStack(stack *st, int num)
{
if (!st) return CreateStack(num);
stack *new_st = (stack*)malloc(sizeof(stack));
new_st->next = st;
new_st->num = num;
return new_st;
}
stack *DelStack(stack *st)
{
if (!st) return nullptr;
stack *tmp = st->next;
free(st);
return tmp;
}
stack *ClearSteck(stack *st)
{
st = DelStack(st);
if (st) ClearSteck(st);
int a = 0;
return nullptr;
}
double ReadStack(stack *st)
{
if (!st)
{
puts("\nОшибка при чтении стека!");
getch();
return 0;
}
return st->num;
}
int Priority(char c)
{
switch (c)
{
case '*':case '/': return 3;
case '-':case '+': return 2;
case '(':case ')': return 1;
default: return 0;
}
}
char *gets()
{
fflush(stdin);
int flag = 0;
char *string;
string = (char*)malloc(1);
char symb;
while (true) {
symb = getchar();
if (symb == '\n' && !flag) continue;
if (symb == '\n') break;
string = (char*)realloc(string, flag + 1);
*(string + flag++) = symb;
}
string = (char*)realloc(string, flag + 1);
*(string + flag) = '\0';
return string;
}
Вложения
-
13.2 KB Просмотры: 105
Последнее редактирование модератором: