2017-09-12 25 views
-4

我的rpn-calculator工作,但有问题。问题在于它会打印出每个连续的计算结果。在哪里放置printf以避免在我的rpn计算器中进行多次打印?

我已经尝试了不同的方法来解决这个问题,最新的一个是添加一个整数,每个计算都会增加一个整数,如果这个整数高于0,以及只有一个数字在堆栈上打印。

但是,如果有多个计算正在进行(例如,写入5 5 + 10 5 * *),则会导致打印出10 500个问题,因为第一次计算后堆栈中只有一个项目。

我该如何解决这个问题?

#define MAX_STACK_SIZE 100 
#define MAX_BUFFER_SIZE 100 

char buff[MAX_BUFFER_SIZE]; 
    double x, stack[MAX_STACK_SIZE]; 
    double t; 
    int i, k=0, num_operand=0; 


int main(void) { 

while(x != 'q') { 
    if(scanf("%s", buff) < 1) 
      { return 0; 
} 
if(isdigit(buff[0]) || isdigit(buff[1])) { 
    sscanf(buff, "%lf", &x); 

if (num_operand < MAX_STACK_SIZE) 
        { 
          stack[num_operand]=x; 
          num_operand ++; 
        } else { printf("Make stack bigger\n");} 

} else { 
switch(buff[0]) { 
    case '+': stack[num_operand - 2] = stack[num_operand - 1] + stack[num_operand - 2]; 
               num_operand --; 
               num_operand --; 
               t = stack[num_operand]; 
               k++; 
               num_operand ++; 
               break; 
    case '-': stack[num_operand - 2] = stack[num_operand - 2] - stack[num_operand - 1]; 
               num_operand --; 
               num_operand --; 
               t = stack[num_operand]; 
               k++; 
               num_operand ++; 
               break; 
    case '/': stack[num_operand - 2] = stack[num_operand - 2]/stack[num_operand - 1]; 
               num_operand --; 
               num_operand --; 
               t = stack[num_operand]; 
               k++; 
               num_operand ++; 
               break; 
    case '*': stack[num_operand - 2] = stack[num_operand - 1] * stack[num_operand - 2]; 
               num_operand --; 
               num_operand --; 
               t = stack[num_operand]; 
               k++; 
               num_operand ++; 
               break; 
    } } 
    if (num_operand == 1 && k !=0) { 
     k = 0; 
     printf("%lf \n", t); } 
} 
} 
+2

'x!='q'':'x'的类型是双倍的。 – BLUEPIXY

+0

阅读整个表达式然后对其进行评估,而不是在阅读时逐位评估表达式。 – molbdnilo

+0

注意:'printf(“%lf \ n”,t);'不会打印“10 500”,而是“10.000000 \ n500.000000 \ n”'。细节很重要。 – chux

回答

0

"%s"消耗导致的空格一样' ''\n'一样 - 所以线的端部和所述空间分离器之间的区别消失。

区分输入使用fgets()并处理该行。然后打印结果。 @molbdnilo

它测试q,代码需要测试行的文本内容,而不是double x@BLUEPIXY

int main(void) { 
    char line[MAX_BUFFER_SIZE]; 

    // read line 
    while (fgets(line, sizeof line, stdin) && line[0] != 'q') { 
    // Set up these variables per each line. 
    double x, stack[MAX_STACK_SIZE]; 
    double t; 
    int i, k = 0, num_operand = 0; 

    const char *p = line; 
    char buff[MAX_BUFFER_SIZE]; 
    int n; // # of characters scanned 

    // process tokens 
    while (sscanf(p, "%s %n", buff, &n) == 1) { 
     ... 

     // next token 
     p += n; 
    } // endwhile 

    // print 
    if (num_operand == 1 && k != 0) { 
     k = 0; 
     printf("%lf \n", t); 
     fflush(stdout); 
    } 
    } // endwhile 
+0

p + = n做什么?不是字符指针? – Slayahh

+1

@ sslayf @@Slayahh(p,“%s%n”,buff,&n)','n'为扫描的字符数。 'p + = n;'稍后将'p'增加到地址'n'字符,有效地将'p'(一个'char'指针)设置到下一个要扫描的地方。 – chux

0

代替通过堆叠在堆栈上的数量显示的,确保与命令明确地显示堆栈顶部。


具体的例子。

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

#define MAX_STACK_SIZE 100 
#define MAX_BUFFER_SIZE 100 

char buff[MAX_BUFFER_SIZE]; 
char *curr_buff = buff; 
double stack[MAX_STACK_SIZE]; 
int sp = -1; 

#define prompt " ok>" 

char *getToken(void); 
bool IsNumber(const char *token, double *value); 
char *strlwr(char *s); 
int cmp_charpp(const void *, const void *); 
void push(double value); 
double pop(void); 
void add(void); 
void sub(void); 
void mul(void); 
void Div(void); 
void dot(void); 
void Exit(void); 
void quit(void); 
void bye(void); 
void cr(void); 

struct command { 
    const char *name; 
    void (*func)(void); 
} op_table[] = { 
    {"*" , mul}, 
    {"+" , add}, 
    {"-" , sub}, 
    {"." , dot}, 
    {"/" , Div}, 
    {"=" , dot}, 
    {"add" , add}, 
    {"bye" , bye}, 
    {"cr" , cr}, 
    {"div" , Div}, 
    {"exit", Exit}, 
    {"mul" , mul}, 
    {"quit", quit}, 
    {"sub" , sub}, 
}; 

int main(void) { 
    while(true){ 
     char *token; 

     fputs(prompt, stdout);fflush(stdout); 
     while(token = getToken()){ 
      double value = 0; 
      if(IsNumber(token, &value)){ 
       push(value); 
      } else if(*token){ 
       strlwr(token); 
       struct command *op = 
        bsearch(&token, op_table, 
         sizeof(op_table)/sizeof(*op_table), sizeof(*op_table), 
         cmp_charpp); 
       if(op){ 
        op->func(); 
       } else { 
        fprintf(stderr, "\ncommand '%s' not found!!\n", token); 
        curr_buff = buff; 
        *buff = 0; 
        break; 
       } 
      } 
     } 
    } 
} 

char *getToken(void){ 
    static char token[MAX_BUFFER_SIZE] = ""; 

    if(curr_buff){ 
     if(*curr_buff || curr_buff == buff && (curr_buff = fgets(buff, sizeof buff, stdin))){ 
      int n = 0; 
      if(sscanf(curr_buff, "%s %n", token, &n) == 1){ 
       curr_buff += n; 
       return token; 
      } 
     } 
     *(curr_buff = buff) = 0; 
    } 
    return NULL; 
} 

bool IsNumber(const char *token, double *value){ 
    char ch = 0; 

    *value = FP_NAN; 

    return sscanf(token, "%lf%c", value, &ch)==1; 
} 

void push(double value){ 
    if(sp+1 == MAX_STACK_SIZE){ 
     fprintf(stderr, "\nstack overflow!!\n"); 
     return; 
    } 
    stack[++sp] = value; 
} 

bool IsEmpty(void){ 
    return sp == -1; 
} 

double pop(void){ 
    if(IsEmpty()){ 
     fprintf(stderr, "\nstack is empty!!\n"); 
     return nan(NULL);//FP_NAN; 
    } 
    return stack[sp--]; 
} 

bool pop2(double *top, double *second){ 
    return !isnan(*top = pop()) && !isnan(*second = pop()); 
} 
void add(void){ 
    double top, second; 
    if(pop2(&top, &second)) 
     push(second+top); 
} 
void sub(void){ 
    double top, second; 
    if(pop2(&top, &second)) 
     push(second-top); 
} 
void mul(void){ 
    double top, second; 
    if(pop2(&top, &second)) 
     push(second*top); 
} 
void Div(void){ 
    double top, second; 
    if(pop2(&top, &second)) 
     push(second/top); 
} 
void dot(void){ 
    double top = pop(); 
    if(!isnan(top)){ 
     printf("%g", top);fflush(stdout); 
    } 
} 
void cr(void){ 
    putchar('\n'); 
} 
void Exit(void){ 
    double top = pop(); 
    if(isnan(top)) 
     exit(EXIT_FAILURE); 
    else 
     exit((int)top); 
} 
void quit(void){ 
    char yn[4]; 
    if(!IsEmpty()){ 
     printf("The stack is not empty but will it end?\n"); 
     scanf(" %3[NYny]", yn); 
     if(*yn == 'y' || *yn == 'Y') 
      exit(EXIT_SUCCESS); 
     else 
      while(getchar()!='\n'); 
    }else { 
     exit(EXIT_SUCCESS); 
    } 
} 
void bye(void){ 
    exit(EXIT_SUCCESS); 
} 
char *strlwr(char *s){ 
    for(char *p = s; *p; ++p) 
     *p = tolower(*p); 
    return s; 
} 
int cmp_charpp(const void *a, const void *b){ 
    return strcmp(*(const char **)a, *(const char **)b); 
} 

执行的实施例。

ok>5 5 + 10 5 * * = CR 
500 
ok>bye 
+0

[DEMO](https://ideone.com/gsYfgf) – BLUEPIXY