Мой оператор Switch неверен при использовании strtol? - PullRequest
0 голосов
/ 02 февраля 2010
#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 ]

1 голос
/ 02 февраля 2010

В случае случаев +, *, /, просто сделайте один щелчок и используйте val напрямую вместо второго. Я думаю, это заставит ваш код работать.

1 голос
/ 02 февраля 2010

Похоже, что целое число в той же строке, что и оператор не помещается в стек, а только одно значение выводится. Кроме того, нет необходимости вызывать atoi () при нажатии найденного целого числа, используйте val, так как это результат strtol ().

Простое исправление состоит в том, чтобы вывести поведение по умолчанию из коммутатора, push (val) до оператора switch, и удаление значения по умолчанию должно помочь.

1 голос
/ 02 февраля 2010

Вам нужно проверить, совпадает ли endptr с указателем ввода, чтобы определить, не было ли преобразования:

if(endptr == s)
{
  /* no integer found */
}
0 голосов
/ 22 октября 2013

Функциональная прогулка, которую вы использовали, в порядке.Но практика - это риск.Синтаксис strol:

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

с endptr - это значение , которое устанавливается функцией для следующего символа в строке после числового значения. Необходимо выполнить сбросуказатель endptr на NULL или начало строки

do 
{        
    printf("> ");
    scanf("%s", s);
    endptr = &s[0];
    int val = strtol(s, &endptr, 10);
}
0 голосов
/ 26 апреля 2012

Похоже, что следующий код в основном работает так, как я думаю, вы ожидаете:

#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;
}
0 голосов
/ 02 февраля 2010

Я думаю, вам следует включить весь код в свой коммутатор, если вы хотите, чтобы мы проверили его для вас.

Вы, вероятно, должны показать весь код полной остановки. На что указывает p, например ??1003*

Редактировать: следуя дополнительному коду Патрика

Привет, Патрик,

Вы никогда не используете свою переменную val. Я подозреваю, что это не то, что вы хотите. Вы получаете поведение, которое видите, потому что (предположительно) ваш стек инициализируется нулями, и поэтому ваш «+» добавляет 1 к 0 и затем помещает 1 обратно в стек. Я не уверен, что вы используете strtol правильно.

Cheers, Dan

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...