0

I have this code that evaluates post fix expressions and initially, the code does not have user input but has the expression already defined in the main function like this:

 int main() 
{ 
    char exp[] = "100 200 + 2 / 5 * 7 +"; 
    printf ("%d", evaluation(exp)); 
    return 0; 
} 

and it will display the answer

However, when I change the code to

int main()
{
    char exp[100];
    printf("Enter an expression:");
    scanf("%s", exp);
    printf ("%d", evaluation(exp));
    return 0;
}

it doesn't work and it will give me a random number every time I run it

I really don't understand why this is happening. How do I let the function evaluate user input?

Would greatly appreciate some help. Thank you.

Here is the full code:

/*---------------POSTFIX EVALUATION-----------------------------*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

struct posteval
{
    int head1;
    unsigned size;
    int* expression;
};


struct posteval* newstack(int size)
{
    struct posteval* posteval2=(struct posteval*)malloc(sizeof(struct posteval));

    if(!posteval2)
    {
        return 0;
    }

    posteval2->expression=(int*)malloc(posteval2->size * sizeof(int));
    posteval2->head1= -1;
    posteval2->size = size;

    if(!posteval2->expression)
    {
        return 0;
    }

    return posteval2;

};

// a function to push into the stack for postfix evaluation
void postpush(struct posteval* posteval2, int x)
{
    posteval2->expression[++posteval2->head1] = x ;
}

// a function to pop into the stack for postfix evaluation
int postpop(struct posteval* posteval2)
{
    if(!nothing(posteval2))
    {
        return posteval2->expression[posteval2->head1--];
    }
    return 'E';
}

//a function that checks if the stack has nothing in it
int nothing(struct posteval* posteval2)
{
    return posteval2->head1 == -1;
}

//function that evaluates the postfix expressions
int evaluation(char* exp)
{
    int i;
    int operand;
    int explength=strlen(exp);
    int num1, num2;
    struct posteval* posteval2=newstack(explength);

    if (!posteval2)
    {
        return -1;
    }

    for(i=0; exp[i]; ++i)
    {
        if (exp[i]==' ')
        {
            continue;
        }
        else if (isdigit(exp[i]))
        {
            operand=0;
            while(isdigit(exp[i]))
            {
                operand= operand*10 + (int)(exp[i]-'0');
                i++;
            }
            i--;

            postpush(posteval2, operand);

        }
        else {
            num1 = postpop(posteval2);
            num2 = postpop(posteval2);

            if(exp[i]=='/')
            {
                postpush(posteval2, num2/num1);
            }
            else if(exp[i]=='+')
            {
                postpush(posteval2, num2 + num1);
            }
            else if (exp[i]=='*')
            {
                postpush(posteval2, num2 * num1);
            }
            else if (exp[i]=='-')
            {
                postpush(posteval2, num2 - num1);
            }

        }
    }
    return postpop(posteval2);
}

    int main()
{
    char exp[100];
    printf("Enter an expression:");
    scanf("%c", exp);
    printf ("%d", evaluation(exp));
    return 0;
}
}
  • 2
    `%c` is for a single character. – Mat Dec 12 '19 at 19:48
  • `scanf("%c", exp);` ==> `scanf("%s", exp);` You corrected but you can avoid typos like this by copy/pasting *actual code*. – Weather Vane Dec 12 '19 at 19:52
  • 1
    Read [*How to debug small programs*](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – Basile Starynkevitch Dec 12 '19 at 19:53
  • Thank you for letting me know about this! I've changed %c to %s but it still doesn't work... The result of the evaluation is just the first number of the expression now... – flamethrower Dec 12 '19 at 19:53
  • 4
    `scanf("%s", exp);` stops at the first whitespace. Please use `fgets` but mind the [trailing newline](https://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input/28462221#28462221) which will be included. Oops - edited the link. – Weather Vane Dec 12 '19 at 19:55
  • In support of Weather Vanes comment, have a look at http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html which seems a little cynical at first, but is a very helpful general discussion on input. – Yunnosch Dec 12 '19 at 22:10
  • @WeatherVane 's suggestion worked. I decided to use gets() instead of scanf and it works without a problem – flamethrower Dec 13 '19 at 10:11

1 Answers1

0

Following the suggestion of Yunnosch I edited my answer, so I saw in your code that you used scanf(“%c”, exp);, in the comments collaborators said to you that it is incorrect, and i agree with them, you need to read a line until line-break appear in the input, to do that you could use scanf(“[^\n]”, exp); this scanning format is used to read every character that you put in the input until one of the characters inside the brackets is found, then you will have the string like you expect, for example “100 200 + 2 / 5 * 7 +”, and not “100 200 + 2 / 5 * 7 + \n” which is not like you expect

Maverick
  • 56
  • 3
  • You need to be more careful with quoting code. There is a subtle difference between the quotation marks used in your post and OPs code. Also correct use of markdown for formatting would help, as would more elegant line wrapping. Also, using `scanf()` at all is not what was recommended in the most appreciated ("agreed") and practically OP-accepted comments. If this is to be a separate answer, contrasting the comment, then please contrast it to the comment and explain more specifically how this is better. Consider mentioning the recommended use of `scaf()`s return value, that is important. – Yunnosch Dec 14 '19 at 09:23