Please note, this is a STATIC archive of website www.tutorialspoint.com from 11 May 2019, cach3.com does not collect or store any user information, there is no "phishing" involved.
Tutorialspoint

Compile and Execute C Online

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stddef.h>
#include <math.h>
#include <stdbool.h>

typedef enum
{
    PLUS,      //0
    MINUS,     //1
    DIVIDE,    //2
    MULT,      //3
    REMAINDER, //4
    POWER,     //5
    LPAREN,    //6
    RPAREN,    //7
    NUMBER,    //8
    ERROR,     //9
    EOL        //10
} TokenType;

struct Token
{
    TokenType type;
    int value;
};


int compute(struct Token, struct Token, struct Token);
void parse(void);
void rebuild(struct Token, int);
void gather(void);
struct Token getToken(void);
bool isFinished(void);
int main();

//The current character
char ch;

//The input array
char arr[20];

//The Token input array
struct Token tok[200];

//The size of the Token array
int tokSize = 0;

//A Token
struct Token tk;

//the last call for compute
bool isLast = false;

int main(void)
{
    scanf("%s", arr);
    parse();
    bool fin = false;
    while (!fin)
    {
        gather();
        fin = isFinished();
    }
    
    printf("Result: ");
    printf("%i\n", tok[0].value);
    
    return 0;
}

//Checks to see if all operators have been removed from the token array
bool isFinished()
{
    int fin = 0;
    for (int i = 0; i < tokSize; i++)
    {
        if (tok[i].type >= 0 && tok[i].type < 6)
        {
            fin = fin  + 1;
        }
    }
    if (fin == 0)
    {
        return true;
    }
    return false;
}

//This method seems to still have some bugs in the code
//but does work in a few situations such as 5+5+5+5 and 5*5+5*5
//This method searches for the current highest operator (PEMDAS)
//along with the two adjecent numbers in the index before and after
//the highest operator. Once found, it makes duplicates of the values
//and sends them to compute() which calculates the value of the operation.
//Once returned, gather() then creates a new token with the calculated value
//and passes the value, as well as the initial index to rebuild().
void gather()
{
    int oIndex = 0;
    int aIndex = 0;
    int bIndex = 0;
    
    bool fail = true;
    
    struct Token o;
    struct Token a;
    struct Token b;
    
    struct Token nToken;
    
    for (int i = 0; i < tokSize; i++)
    {
        if (tok[i].type >= 0 && tok[i].type < 6)
        {
            if (tok[i].type >= oIndex)
            {
                oIndex = i;
                aIndex = i - 1;
                bIndex = i + 1;
                fail = false;
            }
        }
    }
    if (fail)
    {
        printf("\n<No More Operators>\n");
        
    }
    else
    {
    
        o = tok[oIndex];
        a = tok[aIndex];
        b = tok[bIndex];
    
        int t = compute(a, o, b);

        nToken.type = NUMBER;
        nToken.value = t;
    }
    rebuild(nToken, oIndex);
}

//Rebuild takes the new computed value from gather() as well as the index of
//the original operator and begins to rebuild the token array.
//The first loop skips the 3 values that have been computed while adding all
//other values back into a secondary array.
//when the array reaches the former operators index - 1, it places the new
//calculated token back into the array for further calculation.
//and fills in the location of the original operator and the operators index + 1
//which have been computed. After the new array has been completed, the old
//array is then overwritten by the new array. gather() is then called again by
//the main method and continues until the array no longer contains any operators
//While I had intended to add the functionality of numbers greater than
//9 as well as accounting for LPAREN and RPAREN, I seem to have run short on
//time as this assignment had taken significantly longer than I had anticipated.
void rebuild(struct Token item, int oIndex)
{
    struct Token newTok[200];
    int oi = oIndex - 1;
    int k = 0;
    for (int i = 0; i < tokSize; i++)
    {
        if (oi == i)
        {
            newTok[k] = item;
            k++;
        }
        else if (i != oIndex && i != oIndex + 1)
        {
            newTok[k] = tok[i];
            k++;
        }
    }
    
    struct Token empty;
    empty.type = EOL;
    empty.value = 0;
    for (int i = 0; i < tokSize; i++)
    {
        if (i < k)
        {
            tok[i] = newTok[i];
        }
        else
        {
            tok[i] = empty;
        }
    }
}

//Takes in three tokens, two number tokens and one operator token
//returns the computed values
int compute(struct Token a, struct Token b, struct Token c)
{
    int x = a.value;
    int o = b.type;
    int y = c.value;
    
    int response = 0;
    int k = x;
    
    switch (o)
    {
        case 0:
        response = x + y;
        break;
        
        case 1:
        response = x - y;
        break;
        
        case 2:
        response = x / y;
        break;
        
        case 3:
        response = x * x;
        break;
        
        case 4:
        response = x % y;
        break;
        
        case 5:
        for (int i = 1; i < y; i++)
        {
            x = x * k;
        }
        response = x;
        break;
        
        default :
        printf("ERROR");
    }
    return response;
}


//Creates the Token and prints the value as it's created.
struct Token getToken()
{
    struct Token to;
    if (isdigit(ch))
    {
        to.type = NUMBER;
        to.value = ch - '0';
        
        printf("%i", to.value);
        printf("     NUMBER\n");
        return to;
    }
    else
    {
        switch (ch)
        {
            case '+':
                to.type = PLUS;
                to.value = 0;
                
                printf("+     PLUS\n");
                break;
            
            case '-':
                to.type = MINUS;
                to.value = 0;
                
                printf("-     MINUS\n");
                break;
            
            case '/':
                to.type = DIVIDE;
                to.value = 0;
                
                printf("/     DIVIDE\n");
                break;
            
            case '*':
                to.type = MULT;
                to.value = 0;
                
                printf("*     MULT\n");
                break;
            
            case '^':
                to.type = POWER;
                to.value = 0;
                
                printf("^     POWER\n");
                break;
            
            case '(':
                to.type = LPAREN;
                to.value = 0;
                
                printf("(     LPAREN\n");
                break;
            
            case ')':
                to.type = RPAREN;
                to.value = 0;
                
                printf(")     RPAREN\n");
                break;
            
            case '%':
                to.type = REMAINDER;
                to.value = 0;
                
                printf("%%     REMAINDER\n");
                break;
            
            default :
                to.type = ERROR;
                to.value = 0;
                
                printf("!     ERROR\n");
                break;
            
        }
    }
    return to;
}

//calls the getToken method and parses the char array
void parse()
{
    int i = 0;
    while (arr[i])
    {
        ch = arr[i];
        tk = getToken();
        tok[i] = tk;
        i++;
        tokSize = tokSize + 1;
    }
}

















Advertisements
Loading...

We use cookies to provide and improve our services. By using our site, you consent to our Cookies Policy.