見出し画像

C言語で逆ポーランド電卓を作る

特に解説などありません。ネットを参考にしてC言語で自作してみました。scanfの使い方でバグが起きるのはC言語あるあるかもしれませんが、そこらへんのメモリ管理などの知識を忘れていて手こずりました。コンパイルはGDB onlineにて。

/******************************************************************************

Welcome to GDB Online.
  GDB online is an online compiler and debugger tool for C, C++, Python, PHP, Ruby, 
  C#, OCaml, VB, Perl, Swift, Prolog, Javascript, Pascal, COBOL, HTML, CSS, JS
  Code, Compile, Run and Debug online from anywhere in world.

*******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define N 256

typedef struct {
    double data[N];
    int top;
} stack;

void initStack(stack *sp, int n) {
    sp->top = n;
}

void printStack(stack *sp){
    
    int i;
    printf("stack-----\n");
    for (i=N-1 ; i >= sp->top ; i--) {
        printf("%f \n",sp->data[i]);
    }
    printf("----------\n");
    
}

void push(stack *sp,double x){
    
    sp->top = (sp->top)-1 ;
    sp->data[sp->top] = x ;
    
}

double pull(stack *sp){
    
    double ans;
    if (sp->top == N) {
        ans = sqrt(-1);
        return ans;
    }else{
        ans = sp->data[sp->top];
        sp->top = (sp->top)+1;
    return ans;
    }
    
}

void addStack(stack *sp){
    
    double a,b;
    
    if(sp->top > N){
        push(sp,sqrt(-1));
    }else{
        a=pull(sp);
        b=pull(sp);
        push(sp,a+b);
    }
    
}
    
void subStack(stack *sp){
    
    double a,b;
    
    if(sp->top > N){
        push(sp,sqrt(-1));
    }else{
        a=pull(sp);
        b=pull(sp);
        push(sp,b-a);
    }
    
}

void mulStack(stack *sp){
    
    double a,b;
    
    if(sp->top > N){
        push(sp,sqrt(-1));
    }else{
        a=pull(sp);
        b=pull(sp);
        push(sp,b*a);
    }
    
}

void divStack(stack *sp){
    
    double a,b;
    
    if(sp->top > N){
        push(sp,sqrt(-1));
    }else{
        a=pull(sp);
        b=pull(sp);
        push(sp,b/a);
    }
    
}

void sinStack(stack *sp){
    
    sp->data[sp->top] = sin(sp->data[sp->top]);

}

void cosStack(stack *sp){
    
    sp->data[sp->top] = cos(sp->data[sp->top]);
    
}

void sinStack_dig(stack *sp){
    
    sp->data[sp->top] = sin(M_PI/180*sp->data[sp->top]);
    
}

void cosStack_dig(stack *sp){
    
    sp->data[sp->top] = cos(M_PI/180*sp->data[sp->top]);
    
}

void logStack(stack *sp){
    
    sp->data[sp->top] = log(sp->data[sp->top]);
    
}

void helpFunc(){
    printf("俺だけの最強の電卓です\n");
    printf("説明------------------------------------------------------\n");
    printf("end\t終わらせます\n");
    printf("help\t使えるコマンド一覧を表示させます\n");
    printf("+,-,*,/\t四則演算ができます\n");
    printf("sin,cos\t三角関数も計算できます\n");
    printf("log\tlogも計算できます\n");
    printf("----------------------------------------------------------\n");
}

int main() {
    char line[N];
    stack myStack;
    double num;

    helpFunc();
    initStack(&myStack,N);
    
    while(1){
        
        printf(">> ");
        scanf("%s",line); //%cを使うと改行がバッファーに残るバグが発生する
        
        num = atof(line);

        if(strcmp(line, "end") == 0){
            break;
        }else if(strcmp(line, "help") == 0){
            helpFunc();
        }else if(strcmp(line, "+") == 0){
            addStack(&myStack);
        }else if(strcmp(line, "-") == 0){
            subStack(&myStack);
        }else if(strcmp(line, "*") == 0){
            mulStack(&myStack);
        }else if(strcmp(line, "/") == 0){
            divStack(&myStack);
        }else if(strcmp(line, "sin") == 0){
            printf("rad表記ですか?y/n \n");
            scanf("%s",line);
            if (strcmp(line, "y") == 0) {
                    sinStack(&myStack);
            }else if(strcmp(line, "n") == 0){
                    sinStack_dig(&myStack);
            }else{
                printf("yかn以外の文字を入力したため計算されませんでした。");
            }
        }else if(strcmp(line, "cos") == 0){
            printf("rad表記ですか?y/n \n");
            scanf("%s",line);
            if (strcmp(line, "y") == 0) {
                    cosStack(&myStack);
            }else if(strcmp(line, "n") == 0){
                    cosStack_dig(&myStack);
            }else{
                printf("yかn以外の文字を入力したため計算されませんでした。");
            }
        }else if(strcmp(line, "log") == 0){
            logStack(&myStack);
        }else if(strcmp(line, "\n") != 0 && num == 0){
            //何もしない
        }else{
            push(&myStack,num);
        }
        
        printStack(&myStack);
        
    }
}

いいなと思ったら応援しよう!