Организовать код для разделения функций в C - PullRequest
1 голос
/ 16 октября 2019

Я делаю упражнение в университете, и вот оно: «Введите уравнение, проверьте, есть ли скобка. Если оно открывается - вставьте в стек. Если оно закрывается - проверьте, является ли головной элемент стекаоткрывающие скобки / круглые скобки. Если стек пуст, уравнение является правильным ". Я сделал код, чтобы проверить его в функции main (). Но необходимо проверить, является ли элемент уравнения скобкой / круглыми скобками в первой функции и сравнить со следующей скобкой / круглыми скобками.

Большое спасибо, если вы мне поможете). КОД НИЖЕ:

#include <stdio.h> <stdlib.h> <string.h>

#define STACK_SIZE 20
#define OVERFLOW -100
#define UNDERFLOW -101

///BEGIN DEFINING
typedef char C;
typedef struct Stack_tag {
    C data[STACK_SIZE];
    size_t size;
} Stack;
///END DEFINING

///BEGIN STACK FUNCTIONS
void Push(Stack* stack, const C value) {
    if (stack->size >= STACK_SIZE) exit(OVERFLOW);

    stack->data[stack->size] = value;
    stack->size++;
}

C Pop(Stack* stack) {
    if (stack->size == 0) exit(UNDERFLOW);

    stack->size--;
    return stack->data[stack->size];
}

C Peek(const Stack* stack) {
    if (stack->size <= 0) exit(UNDERFLOW);
    return stack->data[stack->size - 1];
}

void PrintStackValue(const C value) {
    printf("%c", value);
}

void PrintStack(const Stack* stack, void(*PrintStackValue)(const C)) {
    int i, len = stack->size - 1;
    printf("\nStack %d", stack->size);
    for (i = 0; i < len; i++) {
        PrintStackValue(stack->data[i]);
        printf(" | ");
    }
    if (stack->size != 0) {
        PrintStackValue(stack->data[i]);
    }
    printf("\n");
}
///END STACK FUNCTIONS

///BEGIN OTHER FUNCTIONS
char isBr(char item) {
    switch (item) {
    case '(': return '(';
    case ')': return ')';
    case '[': return '[';
    case ']': return ']';
    case '{': return '{';
    case '}': return '}';
    default: return NULL;
    }
}
void Check(char item, Stack stack) {
    switch (item) {
    case '(': Push(&stack, item);
    case '[': Push(&stack, item);
    case '{': Push(&stack, item);
    case ')': if (Peek(&stack) == '(') Pop(&stack);
    case ']': if (Peek(&stack) == ']') Pop(&stack);
    case '}': if (Peek(&stack) == '}') Pop(&stack);
    }
}
///END OTHER FUNCTIONS
int main()
{
    Stack stack;
    stack.size = 0;
    ///EQUATION
    char* equation;
    int i;
    equation = (char*)malloc(100 * sizeof(char));
    printf("Enter the Equation: \n");
    gets(equation);
    ///CHECKING PROCESS
    ///TODO:
    ///1) SEPARATE FUNCTIONS
    for (i = 0; i < strlen(equation); i++) {
        /*
        if (equation[i] == '(' || equation[i] == '{' || equation[i] == '[') {
            Push(&stack, equation[i]);
        }
        if (equation[i] == ')') {
            if (Peek(&stack) == '(') Pop(&stack);
        }
        if (equation[i] == '}') {
            if (Peek(&stack) == '{') Pop(&stack);
        }
        if (equation[i] == ']') {
            if (Peek(&stack) == '[') Pop(&stack);
        }
        */
        char p = isBr(equation[i]);
        Check(p, stack);

    }



    ///PRINT THE RESULT
    puts(stack.size == 0 ? "FINE" : "NOOPE!!!");
    //PrintStack(&stack, PrintStackValue);

    return 0;
}

1 Ответ

1 голос
/ 16 октября 2019

У вас есть две проблемы:

  • Когда вы передаете структуру стека в Check, функция видит копию стека. Поэтому внесенные вами изменения теряются в main - они были внесены только в копию. Передайте указатель на структуру так же, как вы делали это для функций стековых операций. (Так как переменная stack будет указателем в Check, вы должны передать stack, а не &stack в функции стека.)

  • Случаи вswitch оператор в C не является изолированным. Выполнение «провалится» до следующего случая, если вы не завершите код с помощью break или return.

Ваша функция проверки может выглядеть следующим образом:

void Check(char item, Stack *stack) {
    switch (item) {
    case '(': Push(stack, item); break;
    case '[': Push(stack, item); break;
    case '{': Push(stack, item); break;
    case ')': if (Peek(stack) == '(') Pop(stack); break;
    case ']': if (Peek(stack) == ']') Pop(stack); break;
    case '}': if (Peek(stack) == '}') Pop(stack); break;
    }
}

и вы вызываете его из main следующим образом:

Check(p, &stack);

Дальнейшие наблюдения:

  • Переполнение стека не должно вызывать немедленный выход из программы,,Вместо этого должно появиться сообщение о том, что уравнение искажено.
  • Как отмечается в комментариях, не используйте небезопасную и устаревшую функцию gets. Вместо этого используйте fgets.
  • Нет необходимости выделять буфер из 100 символов в куче с помощью malloc. Просто используйте автоматический массив: char equation[100];. Если вы используете malloc, вы также должны использовать free, прежде чем вернуться с main.
...