2017-09-12 20 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