2017-09-12 1 views
-4

내 rpn- 계산기가 작동하지만 문제가 있습니다. 문제는 그 과정에서 발생하는 모든 연속적인 계산을 인쇄한다는 것입니다.내 rpn 계산기에서 다중 출력을 피하기 위해 printf를 둘 곳은 어디입니까?

나는 이것을 고치기 위해 여러 가지 방법을 시도했다. 최신 계산은 모든 계산에 의해 올라가는 정수를 더하고,이 정수가 0보다 크고 스택에 하나의 숫자 만 인쇄되면 printf가 인쇄된다.

그러나 계산이 여러 번 진행될 때 (예 : 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'의 형식이 double입니다. – 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은 무엇을합니까? p는 char 포인터가 아닌가? – Slayahh

+1

@Slayahh는'sscanf (p, "% s % n", buff, & n)','n'은 스캔 된 문자의 수를가집니다. 'p + = n;'은'n' 문자 뒤에 주소를''p ''증가시키고, 다음에''p''를 효과적으로 스캔하도록 설정합니다. – 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

관련 문제