-1

The program:

  1. evaluates postfix and prefix expressions
  2. reverse a string
  3. parenthesis balancing
  4. decimal to binary conversion
  5. infix to postfix conversion

There a some extra characters (emojis) appended in the output. I would like to fix that.

Also I have used two pop functions with int and char return type how can I reduce it to one single function.

extra characters in the output of decimal to binary conversion, also that one extra left parenthesis when printing "balanced parenthesis"

This a first year college project.

#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#define MAX 20
int stack[MAX], opp1, opp2, top = -1;

struct stack
{
    char stck[20];
    int top;
}
s;
void push(int x)
{
    top++;
    stack[top] = x;
}
int pop()
{
    char c;
    c = stack[top];
    top = top - 1;
    printf("%c", c);
}
char pop1()
{
    if (top == -1)
        return -1;
    else
        return stack[top--];
}
void postfixeval()
{
    char postfix[20];
    int res, i;
    gets(postfix);
    for (i = 0; postfix[i] != '\0'; i++)
    {
        if (isdigit(postfix[i]))
        {
            push(postfix[i] - 48);
        }
        else
        {
            opp2 = pop();
            opp1 = pop();
            switch (postfix[i])
            {
                case '+':
                    push(opp1 + opp2);
                    break;
                case '-':
                    push(opp1 - opp2);
                    break;
                case '*':
                    push(opp1 *opp2);
                    break;
                case '/':
                    push(opp1 / opp2);
                    break;
                case '^':
                    res = pow(opp1, opp2);
                    break;
            }
        }
    }
    printf("result is %d \n", pop());
}
void prefixeval()
{
    int len;
    char prefix[20];
    int res, i;
    gets(prefix);
    len = strlen(prefix);
    for (i = len - 1; i >= 0; i--)
    {
        if (isdigit(prefix[i]))
        {
            push(prefix[i] - 48);
        }
        else
        {
            opp1 = pop();
            opp2 = pop();
            switch (prefix[i])
            {
                case '+':
                    push(opp1 + opp2);
                    break;
                case '-':
                    push(opp1 - opp2);
                    break;
                case '*':
                    push(opp1 *opp2);
                    break;
                case '/':
                    push(opp1 / opp2);
                    break;
                case '^':
                    res = pow(opp1, opp2);
                    push(res);
                    break;
            }
        }
    }
    printf("result is %d \n", pop());
}

int match(char a, char b)
{
    if (a == '[' && b == ']')
        return 1;
    if (a == '{' && b == '}')
        return 1;
    if (a == '(' && b == ')')
        return 1;
}
int check(char exp[])
{
    int i;
    char temp;
    for (i = 0; i < strlen(exp); i++)
    {
        if (exp[i] == '(' || exp[i] == '{' || exp[i] == '[')
            push(exp[i]);
        if (exp[i] == ')' || exp[i] == '}' || exp[i] == ']')
            if (top == -1)
            {
                return 0;
            }
        else
        {
            temp = pop();
            if (!match(temp, exp[i]))
            {
                printf("Mismatched parentheses are : ");
                printf("%c and %c\n", temp, exp[i]);
                return 0;
            }
        }
    }
    if (top == -1)
    {
        printf("Balanced Parentheses\n");
        return 1;
    }
    else
    {
        return 0;
    }
}
void dectobin(int n)
{
    while (n != 0)
    {
        push(n % 2);
        n = n / 2;
    }
    while (top != -1)
    {
        printf("%d", pop());
    }
}
int priority(char x)
{
    if (x == '(')
        return 0;
    if (x == '+' || x == '-')
        return 1;
    if (x == '*' || x == '/')
        return 2;
}
void intopost()
{
    char exp[100];
    char *e, x;
    printf("Enter the expression : \n");
    scanf("%s", exp);
    printf("\n");
    e = exp;

    while (*e != '\0')
    {
        if (isalnum(*e))
            printf("%c ", *e);
        else if (*e == '(')
            push(*e);
        else if (*e == ')')
        {
            while ((x = pop1()) != '(')
                printf("%c ", x);
        }
        else
        {
            while (priority(stack[top]) >= priority(*e))
                printf("%c ", pop1());
            push(*e);
        }
        e++;
    }

    while (top != -1)
    {
        printf("%c ", pop1());
    }
}

int main()
{
    int ch, i, len;
    char postfix[20], prefix[20], str[30];
    do {
        printf("\n----STACK APPLICATIONS----\n");
        printf("1.postfix expression evaluation\n2.prefix expression evaluation\n3.reverse a string\n4.paranthesis balancing\n5.decimal to binary\n6.infix to postfix\n7.exit\n");
        printf("enter choice");
        scanf("%d", &ch);
        switch (ch)
        {
            case 1:
                {
                    printf("enter postfix expression\n");
                    scanf("%c", &postfix);
                    postfixeval();
                    break;
                }
            case 2:
                {

                    printf("enter prefix expression\n");
                    scanf("%c", prefix);
                    prefixeval();
                    break;
                }
            case 3:
                {
                    printf("enter string\n");
                    scanf("%s", str);
                    len = strlen(str);
                    for (i = 0; i < len; i++)
                    {
                        push(str[i]);
                    }
                    printf("reversed string is:");
                    for (i = 0; i < len; i++)
                    {
                        pop();
                    }
                    break;
                }
            case 4:
                {

                    char exp[20];
                    int valid;
                    printf("Enter an algebraic expression : \n");
                    scanf("%s", exp);
                    valid = check(exp);
                    if (valid == 1)
                    {
                        printf("Valid expression\n");
                    }
                    else
                    {
                        printf("Invalid expression\n");
                    }
                    break;
                }
            case 5:
                {
                    int dec;
                    printf("enter decimal number\n");
                    scanf("%d", &dec);
                    dectobin(dec);
                    break;
                }
            case 6:
                {
                    intopost();
                    break;
                }
            case 7:
                {
                    exit(0);
                }
            default:
                printf("invalid choice\n");
        }
    } while (ch != 7);
}

Here are the additional characters appended with the output

halfer
  • 19,824
  • 17
  • 99
  • 186
  • 4
    Some good advice: Learn to do basic debugging. Run your program in a debugger and step thru the code line by line to find out where things first start to go wrong. – kaylum Aug 19 '22 at 05:53
  • 1
    Comment out almost all of the code and focus on making a single "function" work as you want it to... Beginners often think they'll start debugging AFTER the text of the program is entered. Experienced people develop 'incrementally', always testing that each minor change works... – Fe2O3 Aug 19 '22 at 05:54
  • 1
    `scanf("%c"` needs to be `scanf(" %c"`. Because `%c` will match all characters including the newline character the the previous `scanf` did not consume. The extra space in front of the `c` tells `scanf` to skip all whitespaces. – kaylum Aug 19 '22 at 05:54
  • first problem I see is `scanf("%c", &postfix);`. The `"%c"` format specifier is looking for a pointer to a single `char`, you're giving it a pointer to a `char` array. Based on the instructions you print, the user should input a string, and you should change that to `scanf("%19s", postfix);`. `"%s"` says input a string, the 19 limits it to 19 input chars +1 for the `NUL` terminator so you won't overflow `postfix`, and no `&` b/c in this context `postfix` decays to a pointer to its first element, a `char*`, which is what `"%s"` wants. – yano Aug 19 '22 at 06:16
  • 1
    quite a few [warnings here](https://godbolt.org/z/7Er665zrj), you should fix them, as they can lead to undefined or unexpected behavior. Also, [never use `gets`](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) – yano Aug 19 '22 at 06:19
  • @palak rathore, Why does code use `prefix[i] - 48` and not `prefix[i] - '0'`? – chux - Reinstate Monica Aug 19 '22 at 07:14
  • Dont post pictures of text, post text as properly formatted text. Output is text thjat can be copy/pasted. Also post real code, look closely at what you posted – Jabberwocky Aug 19 '22 at 07:27

1 Answers1

1

Here is one 'improvement' that you should learn about 'C'.

 printf(
     "1.postfix expression evaluation\n"
     "2.prefix expression evaluation\n"
     "3.reverse a string\n"
     "4.paranthesis balancing\n"
     "5.decimal to binary\n"
     "6.infix to postfix\n"
     "7.exit\n"
);

The compiler will 'join-up' those 'segments' (because there is no comma between a close quote and the next open quote.)

Once you have that, you can go back to basics and get this much displaying and functioning:

 printf(
     // "1.postfix expression evaluation\n"
     // "2.prefix expression evaluation\n"
     // "3.reverse a string\n"
     // "4.paranthesis balancing\n"
     // "5.decimal to binary\n"
     // "6.infix to postfix\n"
     "7.exit\n"
);

Don't try to run before you can walk...

To demonstrate 'incremental development' and 'learning/exploring':

// test.c - string segments in source code
#include <stdio.h>

int main() {
    printf(
        "Hello "
        "World!\n"
    );

    return 0;
}
Fe2O3
  • 6,077
  • 2
  • 4
  • 20