使用strtol时,我的Switch语句是否不正确?

时间:2010-02-02 14:18:43

标签: c

#define MAX 100

int *p;
int *tos;
int *bos;

void push(int i);
int pop(void);   



int main ()
{    
int a,b;    
char s[80];

p = (int *) malloc(MAX*sizeof(int));    /* get stack memory */
if (!p)
{
    printf("Allocation Failure\n");
    exit(1);
}


tos = p;
bos = p + MAX-1;

printf("\nRPN Calculator\n");
printf("Enter 'i' for integer mode\n");
printf("Enter 'f' for floating point mode\n");
printf("Enter 'q' to quit\n");
char *endptr;


do {        
    printf("> ");
    scanf("%s", s);
    int val = strtol(s, &endptr, 10);

    if (*endptr == '\0')
    {

        //printf("Got only the integer: %d\n", val);


    }
    else{   printf("operator: %s\n", endptr); 
        printf("Got the integer: %d\n", val);
    }

        /* tests */


    switch(*endptr) {
        case 'i':
            printf("(Integer Mode)\n");
            break;
        case 'f':
            printf("(Floating Point Mode)\n");
            break;
        case '+':
            a = pop();
            b = pop();
            printf("%d\n",a);
            printf("%d\n",b);
            printf("%d\n", a+b);
            push(a+b);
            break;

                    case '-':
            a = pop();
            b = pop();
            printf("%d\n", b-a);
            push(b-a);
            break;  
        case '*':
            a = pop();
            b = pop();
            printf("%d\n", a*b);
            push(a*b);
            break;
        case '/':
            a = pop();
            b = pop();
            if(a == 0){
                printf("Cannot divide by zero\n");
                break;
            }

            printf("%d\n", b/a);
            push(b/a);
            break;
        case '.':
            a = pop();
            push(a);
            printf("Current value on top of stack: %d\n", a);

            break;  
        default:
            push(atoi(s));
    }

} while (*s != 'q'); 
        //end do while loop
    return 0;
}   


// Put an element on the stack

void push (int i)
{
if (p > bos){
    printf("Stack Full\n");
    return;
}
*p = i;
p++;
}

// Get the element from the top of the stack

int pop (void)
{
p--;
if(p < 0) {
    printf("Stack Underflow\n");
    return 0;
}
return *p;
}

我认为我的switch语句不正确。我使用strtol来解析整数,我可以看到它正在工作:

  

2+
  运营商:+
  得到了整数:2

但如果我试试这个:

  

1
  2 +

我明白了:

  

运营商:+
  得到了整数:2
  1
  0
  1

我应该得到一个2而不是0和3而不是1的总和。任何想法?

6 个答案:

答案 0 :(得分:1)

您需要检查endptr是否与输入指针相同,以确定是否没有发生转换:

if(endptr == s)
{
  /* no integer found */
}

答案 1 :(得分:1)

看起来同一行上的整数与操作符没有被压入堆栈,只有单个值似乎被推送。此外,在推送找到的整数时不需要调用atoi(),因为它是strtol()的结果,所以使用val。

简单的解决方法是在switch语句之前将默认行为移出交换机 push(val),并删除默认行为。

答案 2 :(得分:1)

在+,*,/ case的情况下,只需执行一次弹出并直接使用val而不是第二次弹出。我想这会使你的代码工作。

答案 3 :(得分:0)

如果您希望我们为您检查,我认为您应该在交换机中包含所有代码。

您应该完整停止显示所有代码。 p指向什么,例如?

编辑:遵循Patrick的额外代码

嗨帕特里克,

你永远不会真正使用你的val变量。我怀疑这不是你想要的。你得到了你看到的行为,因为(大概)你的堆栈初始化为零,所以你的'+'加1到0,然后将1推回堆栈。我不确定你是否正确使用了strtol。

干杯, 丹

答案 4 :(得分:0)

以下代码似乎主要按我认为您的预期执行:

#include <stdio.h>
#include <stdlib.h>


#define MAX 100

int *p;
int *tos;
int *bos;

void push(int i);
int pop(void);   



int main ()
{    
int a,b;    
char s[80];

p = (int *) calloc(MAX,sizeof(int));    /* get stack memory */
if (!p)
{
    printf("Allocation Failure\n");
    exit(1);
}


tos = p;
bos = p + MAX-1;

printf("\nRPN Calculator\n");
printf("Enter 'i' for integer mode\n");
printf("Enter 'f' for floating point mode\n");
printf("Enter 'q' to quit\n");
char *endptr;

p++;

do {        
    printf("> ");
    scanf("%s", s);
    int val = strtol(s, &endptr, 10);

    if (*endptr == '\0')
    {

        //printf("Got only the integer: %d\n", val);


    }
    else{   printf("operator: %s\n", endptr); 
        printf("Got the integer: %d\n", val);
    }

        /* tests */


    if( endptr != s )
    {
        push(val);
    }



    switch(*endptr) {
        case 'i':
            printf("(Integer Mode)\n");
            break;
        case 'f':
            printf("(Floating Point Mode)\n");
            break;
        case '+':
            a = pop();
            b = pop();
            printf("%d\n",a);
            printf("%d\n",b);
            printf("%d\n", a+b);
            push(a+b);
            break;

                    case '-':
            a = pop();
            b = pop();
            printf("%d\n", b-a);
            push(b-a);
            break;  
        case '*':
            a = pop();
            b = pop();
            printf("%d\n", a*b);
            push(a*b);
            break;
        case '/':
            a = pop();
            b = pop();
            if(a == 0){
                printf("Cannot divide by zero\n");
                break;
            }

            printf("%d\n", b/a);
            push(b/a);
            break;
        case '.':
            a = pop();
            push(a);
            printf("Current value on top of stack: %d\n", a);

            break;  
    }

} while (*s != 'q'); 
        //end do while loop
    return 0;
}   


// Put an element on the stack

void push (int i)
{
if (p > bos){
    printf("Stack Full\n");
    return;
}
*p = i;
printf("pushed %d\n", *p);
p++;
}

// Get the element from the top of the stack

int pop (void)
{
p--;
if(p < tos) {
    printf("Stack Underflow\n");
    return 0;
}
printf("popped %d\n", *p);
return *p;
}

答案 5 :(得分:0)

你使用的功能是很好的。但是pramenter是冒险的。 strol的语法是

`long int strtol (const char* str, char** endptr, int base);

endptr 值,由函数设置为数值后str中的下一个字符。您必须将endptr指针重置为NULL或str的开头

do 
{        
    printf("> ");
    scanf("%s", s);
    endptr = &s[0];
    int val = strtol(s, &endptr, 10);
}