atoi problem

Discussion in 'C++' started by Henry Jordon, Jul 13, 2004.

  1. Henry Jordon

    Henry Jordon Guest

    This is a piece of code that I have left to complete my project. I
    have hopefully one small error that needs to be fixed. This portion of
    the code evaluates the postfix notation that is passed to it. I have
    marked the error line. Thank you very much for your help.


    void evaluates(char *postfix)
    {
    int position;
    char number1, number2, number3=0;
    char symbol, answer;
    stack number_stack;

    for(position=0; postfix[position] !='\0'; position++)
    {
    symbol=postfix[position];
    if(symbol=='0'||symbol=='1'||symbol=='2'||symbol=='3'||symbol=='4'||symbol=='5'||symbol=='6'||symbol=='7'||symbol=='8'||symbol=='9')
    {
    number_stack.push(symbol);
    }
    else
    {
    number2=number_stack.pop();
    number1=number_stack.pop();
    if(symbol=='+')
    {
    number3=number1+number2;
    }
    else if(symbol=='-')
    {
    number3=number1-number2;
    }
    else if(symbol=='*')
    {
    number3=number1*number2;
    }
    else if(symbol=='/')
    {
    number3=number1/number2;
    }
    else if(symbol=='^')
    {
    number3=number2*number2;
    }
    number_stack.push(number3);
    }
    }
    answer=number_stack.pop();
    The error comes here cannot conver char to const char*. I want to
    convert the answer into an integer value, not ASCII values
    cout<<"The answer evaluates to: "<<atoi(answer)<<endl;
    }

    again thank you very much for your help.
     
    Henry Jordon, Jul 13, 2004
    #1
    1. Advertising

  2. Henry Jordon

    Artie Gold Guest

    Henry Jordon wrote:
    > This is a piece of code that I have left to complete my project. I
    > have hopefully one small error that needs to be fixed. This portion of
    > the code evaluates the postfix notation that is passed to it. I have
    > marked the error line. Thank you very much for your help.
    >
    >
    > void evaluates(char *postfix)
    > {
    > int position;
    > char number1, number2, number3=0;
    > char symbol, answer;
    > stack number_stack;
    >
    > for(position=0; postfix[position] !='\0'; position++)
    > {
    > symbol=postfix[position];
    > if(symbol=='0'||symbol=='1'||symbol=='2'||symbol=='3'||symbol=='4'||symbol=='5'||symbol=='6'||symbol=='7'||symbol=='8'||symbol=='9')
    > {
    > number_stack.push(symbol);
    > }
    > else
    > {
    > number2=number_stack.pop();
    > number1=number_stack.pop();
    > if(symbol=='+')
    > {
    > number3=number1+number2;
    > }
    > else if(symbol=='-')
    > {
    > number3=number1-number2;
    > }
    > else if(symbol=='*')
    > {
    > number3=number1*number2;
    > }
    > else if(symbol=='/')
    > {
    > number3=number1/number2;
    > }
    > else if(symbol=='^')
    > {
    > number3=number2*number2;

    I don't think this is what you mean here.
    > }
    > number_stack.push(number3);
    > }
    > }
    > answer=number_stack.pop();
    > The error comes here cannot conver char to const char*. I want to
    > convert the answer into an integer value, not ASCII values
    > cout<<"The answer evaluates to: "<<atoi(answer)<<endl;
    > }
    >
    > again thank you very much for your help.


    The variable `answer' is of type `char'. The function atoi() takes a
    parameter of type `const char *'. What's not to understand? ;-)

    [To get the number designated by a char that's a digit, subtract '0';
    for example, '3' - '0' = 3.]

    HTH,
    --ag

    --
    Artie Gold -- Austin, Texas

    "What they accuse you of -- is what they have planned."
     
    Artie Gold, Jul 13, 2004
    #2
    1. Advertising

  3. Henry Jordon

    Jack Klein Guest

    On 12 Jul 2004 16:14:45 -0700, (Henry Jordon)
    wrote in comp.lang.c++:

    > This is a piece of code that I have left to complete my project. I
    > have hopefully one small error that needs to be fixed. This portion of
    > the code evaluates the postfix notation that is passed to it. I have
    > marked the error line. Thank you very much for your help.
    >
    >
    > void evaluates(char *postfix)
    > {
    > int position;
    > char number1, number2, number3=0;
    > char symbol, answer;
    > stack number_stack;
    >
    > for(position=0; postfix[position] !='\0'; position++)
    > {
    > symbol=postfix[position];
    > if(symbol=='0'||symbol=='1'||symbol=='2'||symbol=='3'||symbol=='4'||symbol=='5'||symbol=='6'||symbol=='7'||symbol=='8'||symbol=='9')


    In addition to Artie's correct answer, do you realize that you could
    include <cctype> and replace the line above with:

    if (std::isdigit(symbol))

    ???

    Then replace the rest with a switch() statement?

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Jul 13, 2004
    #3
  4. Henry Jordon wrote:
    [snip]
    > else if(symbol=='^')
    > {
    > number3=number2*number2;
    > }
    > number_stack.push(number3);
    > }
    > }
    > answer=number_stack.pop();
    > The error comes here cannot conver char to const char*. I want to
    > convert the answer into an integer value, not ASCII values


    This brings up a question immediatly.
    You are dealing with numbers here. So why not have a stack
    of int and do all calculations with int instead of char. This
    way you get the desired result without any problems. This would
    also deal easily with the problem of eg. doing 3 + 4 + 5 where
    you would need more then 1 digit to represent the result.
    All you need to do would be to convert the digit characters from
    your symbol stack to an integer before you push it onto the number
    stack.

    BTW: Have you learned about the function isdigit()?

    if(symbol=='0'||symbol=='1'||symbol=='2'||symbol=='3'||symbol=='4'||symbol=='5'||symbol=='6'||symbol=='7'||symbol=='8'||symbol=='9')
    > {
    > number_stack.push(symbol);
    > }


    This would become simpler by using isdigit

    if( isdigit( symbol ) )
    {
    number_stack.push( symbol );
    }

    or if you change to the proposed strategy of using an int stack for the
    numbers:

    if( isdigit( symbol ) )
    {
    number_stack.push( symbol - '0' );
    }

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Jul 13, 2004
    #4
  5. Henry Jordon wrote:
    > This is a piece of code that I have left to complete my project. I
    > have hopefully one small error that needs to be fixed. This portion of
    > the code evaluates the postfix notation that is passed to it. I have
    > marked the error line. Thank you very much for your help.
    >
    >
    > void evaluates(char *postfix)
    > {
    > int position;
    > char number1, number2, number3=0;
    > char symbol, answer;
    > stack number_stack;
    >
    > for(position=0; postfix[position] !='\0'; position++)
    > {
    > symbol=postfix[position];
    > if(symbol=='0'||symbol=='1'||symbol=='2'||symbol=='3'||symbol=='4'||symbol=='5'||symbol=='6'||symbol=='7'||symbol=='8'||symbol=='9')
    > {
    > number_stack.push(symbol);
    > }
    > else
    > {
    > number2=number_stack.pop();
    > number1=number_stack.pop();
    > if(symbol=='+')
    > {
    > number3=number1+number2;
    > }
    > else if(symbol=='-')
    > {
    > number3=number1-number2;
    > }
    > else if(symbol=='*')
    > {
    > number3=number1*number2;
    > }
    > else if(symbol=='/')
    > {
    > number3=number1/number2;
    > }
    > else if(symbol=='^')
    > {
    > number3=number2*number2;
    > }
    > number_stack.push(number3);
    > }
    > }
    > answer=number_stack.pop();
    > The error comes here cannot conver char to const char*. I want to
    > convert the answer into an integer value, not ASCII values
    > cout<<"The answer evaluates to: "<<atoi(answer)<<endl;
    > }
    >
    > again thank you very much for your help.


    Another strategy is to use a table or map of
    <symbol, function pointer> pairs:

    typedef int (*Function_Pointer)(int number1, int number2);
    int Add(int, int);
    int Subtract(int, int);
    int Multiply(int, int);
    int Divide(int, int);
    int Power(int, int);

    struct Operator_Record
    {
    char symbol;
    Function_Pointer function;
    };

    Operator_Record operator_table[] =
    {
    {'+', Add}, {'-', Subtract},
    {'*', Multiply}, {'/', Divide},
    {'^', Power}
    };
    const unsigned int MAX_OPR_FUNCS =
    sizeof(operator_table) / sizeof(operator_table[0]);

    int Add(int a, int b)
    {
    return a + b;
    }

    int evaluate(std::string text)
    {
    // ...
    if (isdigit(text[position]))
    {
    number_stack.push(text[position])
    }
    else
    {
    unsigned int i;
    for (i = 0; i < MAX_OPR_FUNCS; ++i)
    {
    if (operator_table.symbol == text[position])
    {
    int num2 = atoi(number_stack.pop());
    int num1 = atoi(number_stack.pop());
    int result;
    result = (operator_table.function)(num1, num2);
    }
    }
    }
    // ...
    }



    --
    Thomas Matthews

    C++ newsgroup welcome message:
    http://www.slack.net/~shiva/welcome.txt
    C++ Faq: http://www.parashift.com/c -faq-lite
    C Faq: http://www.eskimo.com/~scs/c-faq/top.html
    alt.comp.lang.learn.c-c++ faq:
    http://www.raos.demon.uk/acllc-c /faq.html
    Other sites:
    http://www.josuttis.com -- C++ STL Library book
     
    Thomas Matthews, Jul 13, 2004
    #5
  6. Thomas Matthews wrote:
    >

    [snip]

    Not to question the idea of a function table
    (it is a good one).

    But: To the OP

    The posted code contains some problems. I don't know
    if Thomas left them in intenionally (after all it
    is your assignement), but beware, eg.:
    He doesn't do anything with the result of the computation,
    and your atoi() problem is still there :)

    >
    > int evaluate(std::string text)
    > {
    > // ...
    > if (isdigit(text[position]))
    > {
    > number_stack.push(text[position])
    > }
    > else
    > {
    > unsigned int i;
    > for (i = 0; i < MAX_OPR_FUNCS; ++i)
    > {
    > if (operator_table.symbol == text[position])
    > {
    > int num2 = atoi(number_stack.pop());
    > int num1 = atoi(number_stack.pop());
    > int result;
    > result = (operator_table.function)(num1, num2);
    > }
    > }
    > }
    > // ...
    > }
    >


    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Jul 13, 2004
    #6
  7. Henry Jordon

    David Rubin Guest

    (Henry Jordon) wrote in message news:<>...

    > void evaluates(char *postfix)


    'postfix' should have type 'const char *'. Also, 'evaluates' (why
    "s"?) should either return the answer (probably as a double, but not
    necessarily), or it should take a 'result' parameter and return a
    status code: 0 for success, and a non-zero value otherwise.

    > {
    > int position;
    > char number1, number2, number3=0;
    > char symbol, answer;
    > stack number_stack;


    Some consider it bad practice to use 'stack' since the STL defines a
    'std::stack' type. If you import the 'std' namespace (at some point),
    you might run into problems. It's better to use 'Stack' or 'my_Stack'
    or some namespace-qualified stack type. Also, since you are
    *evaluating* the expression, I would expect 'number_stack' to be a
    stack of 'int' values, and similarly, your temporary variables should
    have type 'int' as well.

    > for(position=0; postfix[position] !='\0'; position++)


    'position' is local to this loop. Therefore, you may declare it inside
    the 'for' statement. However, since 'postfix' is a null-terminated
    string, a common idiom is to increment and dereference 'postfix':

    while(char symbol = *postfix)

    Likewise, 'number1', 'number2', and 'number3' are local to the for
    loop.

    > {
    > symbol=postfix[position];

    [rearranged]
    if(symbol=='0'
    || symbol=='1'
    || symbol=='2'
    || symbol=='3'
    || symbol=='4'
    || symbol=='5'
    || symbol=='6'
    || symbol=='7'
    || symbol=='8'
    || symbol=='9')

    More concisely expressed as

    if(std::strchr("0123456789", symbol) != 0)
    > {
    > number_stack.push(symbol);
    > }
    > else
    > {
    > number2=number_stack.pop();
    > number1=number_stack.pop();
    > if(symbol=='+')
    > {
    > number3=number1+number2;
    > }
    > else if(symbol=='-')
    > {
    > number3=number1-number2;
    > }
    > else if(symbol=='*')
    > {
    > number3=number1*number2;
    > }
    > else if(symbol=='/')
    > {
    > number3=number1/number2;


    What if 'number2' is 0? Do you want to assert?
    > }
    > else if(symbol=='^')
    > {
    > number3=number2*number2;
    > }
    > number_stack.push(number3);


    You don't really need 'number3' since you can just 'push' the result
    back onto the stack in every operator branch.

    > }
    > }
    > answer=number_stack.pop();
    > The error comes here cannot conver char to const char*. I want to
    > convert the answer into an integer value, not ASCII values
    > cout<<"The answer evaluates to: "<<atoi(answer)<<endl;
    > }


    Printing the result to standard output makes this function very
    difficult to programmatically verify. How are you planning to test
    this function? If you returned the result in a pararmeter (and
    returned a status code from the function), you can easily test each
    operand branch as well as correct execution for invalid expressions.
    For example, assuming the function

    int evaluate(const char *postfix, double *result);
    // Evalute the specified 'postfix' mathematical expression
    // and store the result in the specified 'result' parameter.
    // Return 0 on success, and a non-zero value otherwise. In
    // particular, if 'postfix' is an invalid or incomplete
    // expression, a non-zero value is returned, and the value
    // of 'result' is indeterminate. The behavior is undefined
    // unless 'postfix' is a null-terminated string and 'result'
    // is a valid pointer.

    and a working (tested) function

    std::string infix2postfix(const char *infix);

    You can test (portions of) 'evaluate' as follows:

    // Basic Evaluation Test
    const struct {
    const char *d_infix; // valid infix expression
    double d_result; // result of 'infix' evaluation
    } DATA[] =
    {
    // infix result
    //------------------ -----------------
    { "0.0", 0.0 },
    { "1.0", 1.0 },
    { "12.0", 12.0 },
    { "123.0", 123.0 },
    { "0.1", 0.1 },
    { "0.12", 0.12 },
    { "0.123", 0.123 },
    { "1.0 + 2.0", 1.0 + 2.0 },
    { "3.0 - 4.0", 3.0 - 4.0 },
    { "5.0 * 6.0", 5.0 * 6.0 },
    { "7.0 / 8.0", 7.0 / 8.0 },
    { "1.0 + 2.0 - 3.0", 1.0 + 2.0 - 3.0 },
    { "1.0 + 2.0 * 3.0", 1.0 + 2.0 * 3.0 },
    { "1.0 + 2.0 / 3.0", 1.0 + 2.0 / 3.0 },
    { "1.0 - 2.0 * 3.0", 1.0 - 2.0 * 3.0 },
    { "1.0 - 2.0 / 3.0", 1.0 - 2.0 / 3.0 },
    { "1.0 * 2.0 / 3.0", 1.0 * 2.0 / 3.0 },
    { "1.0 * 2.0 + 3.0", 1.0 * 2.0 + 3.0 },
    { "1.0 / 2.0 - 3.0", 1.0 / 2.0 - 3.0 },
    };
    enum { DATA_SIZE = sizeof DATA / sizeof *DATA };

    for(int i=0; i < DATA_SIZE; ++i){
    std::string postfix = infix2postfix(DATA.d_infix);
    const double RESULT = DATA.d_result;
    double result;
    int rc = evaluate(postfix.c_str(), &result);

    if(veryVerbose){
    std::cout << '\t'
    << "i = " << i << ' '
    << "rc = " << rc << ' '
    << "infix = " << infix << ' '
    << "RESULT = " << result << ' '
    << "result = " << result
    << std::endl;
    }
    assert(0 == rc && RESULT == result);
    }

    HTH, /david
     
    David Rubin, Jul 13, 2004
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. lonelyplanet999
    Replies:
    8
    Views:
    43,225
  2. Magig Boatman
    Replies:
    1
    Views:
    474
    Russell Hanneken
    Jul 11, 2003
  3. tolkien

    Problem with atoi()

    tolkien, Sep 9, 2007, in forum: C Programming
    Replies:
    25
    Views:
    655
    David Thompson
    Sep 23, 2007
  4. Sanchit

    Problem with atoi and strlod

    Sanchit, Apr 13, 2008, in forum: C Programming
    Replies:
    6
    Views:
    421
    Keith Thompson
    Apr 14, 2008
  5. Marcelo De Brito

    A Minor Problem With atoi() And Negative Numbers

    Marcelo De Brito, Mar 7, 2010, in forum: C Programming
    Replies:
    12
    Views:
    4,750
    Nick Keighley
    Mar 9, 2010
Loading...

Share This Page