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);
}
}