Сложненький калькулятор.

  • На форуме работает ручное одобрение пользователей. Это значит, что, если Ваша причина регистрации не соответствует тематике форума, а также Вы используете временную почту, Ваша учётная запись будет отклонена без возможности повторной регистрации. В дальнейшем - пожизненная блокировка обоих аккаунтов за создание мультиаккаунта.
  • Мы обновили Tor зеркало до v3!
    Для входа используйте следующий url: darkv3nw2...bzad.onion/
  • Мы вновь вернули telegram чат форуму, вступайте, общайтесь, задавайте любые вопросы как администрации, так и пользователям!
    Ссылка: https://t.me/chat_dark_time

Dendy

Участник

Dendy

Участник
8 Ноя 2016
79
83
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Калькулятор поддерживает ввод натуральных чисел (это типо >= 0). Выводит double.
Собственно выкладываю сюда исходник, может кому нужно будет лабу делать.

f5d2d5e75dd30aa22502cc8fefb489f8.png
Код:
#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;
}
 

Вложения

Последнее редактирование модератором:
  • Лайк
Reactions: Gegantar$

О нас

  • Наше сообщество существует уже много лет и гордится тем, что предлагает непредвзятое, критическое обсуждение различных тем среди людей разных слоев общества. Мы работаем каждый день, чтобы убедиться, что наше сообщество является одним из лучших.

    Dark-Time 2015 - 2022

    При поддержке: XenForo.Info

Быстрая навигация

Меню пользователя