Jump to content

I give up (lots of code but can't fix the little error)

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
4 replies to this topic

#1
Lokantis

Lokantis

    Newbie

  • Members
  • PipPip
  • 17 posts
I am trying to write a program that is basically a calculator that takes a simple string of the expression as input. For now I just want to make it to work with just magic numbers. Later I will try to make it an actual equation solver of some sort.
Anyway the problem I am having is that if you have a single digit number in the expression, the function interprets it wrong. I have no idea what I did wrong. I tested my getNum function several times and it works perfectly with single digit numbers in a string.
Sample I/O:
Input:
printf("%d", calc("52-12/4+41*11+43-12"));
Output:
Num1 is 52. Num 2 is 12. Operator is 2. Result is 40
Num1 is 40. Num 2 is 42. Operator is 4. Result is 0
Num1 is 0. Num 2 is 41. Operator is 3. Result is 0
Num1 is 0. Num 2 is 11. Operator is 1. Result is 11
Num1 is 11. Num 2 is 43. Operator is 2. Result is -32
-32[Press Enter to close window]
As you can see the program reads 42 instead of just the number 4.
int calc(const char expr[])

{

    int terms[256];

    int operators[256];

    int termCount = 0;

    int operatorCount = 0;

    int result = 0;

    int i;

    int operator;

    for (i = 0; expr[i] != '\0'; i++)

    {

        operator = checkOperator(expr[i]); /*identify an operator*/

        if (operator)

        {

            operators[operatorCount] = operator; /*add operator to array*/

            operatorCount++;

        }

        else if (isdigit(expr[i]))

        {

            terms[termCount] = getNum(expr, i); /*read in the whole number considering it's length*/

            i += numDigits(terms[termCount])-1; /*skip the loop variable ahead of the number*/

            termCount++;

        }

    }

    result = terms[0];

    for (i = 0; i < operatorCount; i++) /*perform the operations in order*/

    {

        printf("Num1 is %d. Num 2 is %d. Operator is %d. ", result, terms[i+1], operators[i]);

        result = operate(result, terms[i+1], operators[i]);

        printf("Result is %d\n", result);

    }

    return result;

}


int getNum(const char expr[], int pos) /*Pos is the starting index of the number*/

{

    int i;

    int num = -1;

    char numString[64];

    if (isdigit(expr[pos]))

    {

        for (i = pos; isdigit(expr[i]); i++) /*keep going until the number ends*/

        {

            numString[i-pos] = expr[i]; /*build the number digit by digit*/

        }

        num = atoi(numString);

    }

    return num;

}


int checkOperator(int c) /*identifies the operator, numbers 1-6 represent the respective operators. 0 if the character is not an operator*/

{

    int out = 0;

    if (c == '+')

    {

        out = 1;

    }

    else if (c == '-')

    {

        out = 2;

    }

    else if (c == '*')

    {

        out = 3;

    }

    else if (c == '/')

    {

        out = 4;

    }

    else if (c == '^')

    {

        out = 5;

    }

    else if (c == '%')

    {

        out = 6;

    }

    return out;

}


int operate(int x, int y, int operator) /*do one operation*/

{

    int out;

    int i;

    switch (operator)

    {

        case 1: out = x + y;            break;

        case 2: out = x - y;            break;

        case 3: out = x * y;            break;

        case 4: out = x / y;            break;

        case 5: out = powerOf(x, y);    break;

        case 6: out = x % y;            break;

    }

    return out;

}


int powerOf(int x, int y)

{

    int out = x;

    int i;

    for (i = 0; i < y-1; i++)

    {

        out *= x;

    }

    return out;

}


int numDigits(const int num) /*determine number of digits in a number*/

{

    int count = 0;

    int number = num;

    while (number != 0)

    {

        ++count;

        number /= 10;

    }

    return count;

}


#2
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
I think your getNum function isn't explicitly adding an '\0' after the last digit, so the 12 has 1 overwritten by 4 resulting in 42.
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#3
Lokantis

Lokantis

    Newbie

  • Members
  • PipPip
  • 17 posts
How can I do that? I guessed I would fix the function as this:
int getNum(const char expr[], int pos)

{

    int i;

    int num = -1;

    char numString[64];

    if (isdigit(expr[pos]))

    {

        for (i = pos; isdigit(expr[i]); i++) /*keep going until the number ends*/

        {

            numString[i-pos] = expr[i]; /*build the number digit by digit*/

        }

        numString[(i-pos)+1] = '\0';

        num = atoi(numString);

    }

    return num;

}
But I still get 42 instead of 4

#4
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
Try this:
int getNum(const char expr[], int pos)
{
    int i;
    int num = -1;
    char numString[64];
    if (isdigit(expr[pos]))
    {
        for (i = pos; isdigit(expr[i]); i++) /*keep going until the number ends*/
        {
            numString[i-pos] = expr[i]; /*build the number digit by digit*/
        }
        numString[(i-pos)] = '\0';  //i has been incremented, so no +1 needed
        num = atoi(numString);
    }
    return num;
}

Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#5
Lokantis

Lokantis

    Newbie

  • Members
  • PipPip
  • 17 posts
Finally it works! thanks