#include<stdio.h>
#define MAX 100
int j;
int top = -1;
int stack[MAX];
char expr[MAX];
int isp[] = { 0,19,12,12,13,13,13,0 };
int icp[] = { 20,19,12,12,13,13,13,0 };
typedef enum { lparen, rparen, plus, minus, times, divide, mod, eos, operand }precedence;
void printToken(precedence);
void postfix();
int eval();
precedence getToken(char* , int*);
void push(int );
int pop();
void is_full();
void is_empty();
int main()
{
FILE* fp = fopen(fname, "r");;
char name[100];
while (1) {
printf("파일이름은? : ");
scanf("%s", name);
fgets(stack, MAX_STACK_SIZE, fp);
fclose(fp);
printf(" 후위연산 -> ");
postfix();
printf(" 연산결과 -> %d\n", eval());
}
printf("프로그램 종료");
}
}
precedence getToken(char* symbol, int* n)
{
*symbol = expr[(*n)++];// 후위표기식에서 토큰받기
switch (*symbol)
{
case '(':return lparen;
case ')':return rparen;
case'+':return plus;
case'-':return minus;
case'/':return divide;
case'*':return times;
case'%':return mod;
case' ':return eos;
default: return operand;
}
}
void is_full()
{
if (top == MAX - 1)
printf("FULL");
}
void is_empty()
{
if (top == -1)
printf("EMPTY");
}
void push(int data)
{
if (!is_full)
stack[++top] = data;
else
printf("FULL");
}
int pop()
{
if (!is_empty)
return stack[top--] ;
else
printf("EMPTY");
}
int eval()
{
precedence token;
char symbol;
int op1, op2;
int n = 0;
token = getToken(&symbol, &n);
while (token != eos)
{
if (token == operand)
push(symbol - '0');
else
{
op2 = pop();
op1 = pop();
switch (token)
{
case plus:push(op1 + op2);
break;
case minus:push(op1 - op2);
break;
case times: push(op1 * op2);
break;
case divide:push(op1 / op2);
break;
case mod:push(op1 % op2);
}
}
token = getToken(&symbol, &n);
}
return pop();
}
void postfix()
{
char symbol;
precedence token;
int n = 0;
stack[0] = eos;
for (token == getToken(&symbol, &n); token != eos; token == getToken(&symbol, &n))
{
if (token == operand)
printf("%c", symbol);
else if (token == rparen)
{
while (stack[top] != lparen)
printToken(pop());
pop();
}
else
{
while (isp[stack[top]] >= icp[token])
printToken(pop());
push(token);
}
}
while (token = pop() != eos)
printToken(token);
printf("\n");
}
void printToken(precedence token)
{
switch (token)
{
case lparen: expr[j++] = '(';
break;
case rparen: expr[j++] = '(';
break;
case plus: expr[j++] = +'+';
break;
case minus: expr[j++] = -'-';
break;
case divide: expr[j++] = '/';
break;
case times: expr[j++] = '*';
break;
case mod: expr[j++] = '%';
break;
case eos: expr[j++] = ' ';
return;
}
expr[j++] = ' ';
}
LNK2019뜨는데 아 함수선언하고 구현도다했는데 왜이레ㅐ
이거 어제 그거네
ㅋㅋㅋㅋㅋㅋ 또다시 도와주어서 고마우이....
에러 열라 뜨네
왜 또 댓글 안 올락
calc.c:45:19: error: use of undeclared identifier 'fname'; did you mean 'rename'?
fname 라고 있는데.. 그거 선언이 없음
아 메인 긁어온거라 고치다보니 잘못고친듯
printf("파일이름은? : "); scanf("%s", name); 이게 while 위로 올라가 되겠음. fname 이 name 을 의미하는거네.
fclose(fp); 는 while 밖에 아래로
아항
다했는데 안고쳐지네,,.,.. 눈물난다
심심하다고 재미삼아 할만하다고 하기엔 영 별로구만 - dc Cpp
ㅋㅋㅋㅋㅋ맞아.. ㅠㅠ
while (token = pop() != eos) if (!is_full()) 근데 is_full() return 값 없는거 같은데?
헐미친 왜이렇게썼지 헐..
fgets 에서 expr 에 넣어야 되구
아 나 이게 궁금했는데 메모장에 써져있는 중위표기법을 후기표기법으로 바꾸는거거든 그래서 fgets로 메모장에있는 식을 긁어오는거잖아 그래서 expr은 후위표기스택이고 stack은 중위표기스택인데 왜 expr에 넣는지모르겠어 .. stack에 중위표기식을넣고 postfix()로 고친다고생각했거든
expr 에는 사람이 입력한게 들어감. 여기서는 file 로 입력 받는거구
입력을 받은 다음에, 그걸 stack 를 이용해서 후위로 바꾸는거임
파일 또는 사람(stdin)으로부터 입력을 받으면 어딘가에 저장을 해야 함. 그게 expr 배열. expr 배열에 저장되어 있는거에서 getToken() 에서 하나를 다시 읽은 다음에 적절하게 stack 에 넣음. 근데 여기 소소에는 stack 에 넣는게 없는거 같은데?
아... push(token); 에서 넣는구나.. 소소코드 참... 개떡같이 짜놨네 ㅎㅎ
아.. 내가 반대로했구나.. 스택은 전역에서 선언했어
책 저자 프밍 실력을 알거 같다 ㅎㅎ
ㅋㅋㅋㅋㅋ 진짜 개떡같아 ㅠㅠㅠㅠㅠ 책코드랑 인터넷코드랑 섞이고 이리저리정신없이하다보니 진짜정신업성... 미안 ㅜㅜ
그책 안 보고 다른 책 봐라. c 언어로 저렇게 프로그래밍 하면 커다런 어플은 개발 못 한다. 저렇게 짜면 연습문제 수준 밖에 몬짜요~~ 학교에서 보는 책 아니면 당장 바꾸셈
후유,,,, ㅜㅜㅜ 이렇게 많이 찾아줘서 바꿨는ㄴ데도 안되네... 막막하당
중위 후위 변환하면 범용적인 알고리즘 있음. 그거 보고 c 언어로 그대로 코딩하는게 나을 수도 있음.
일단 이거 해놓은거 너무아까워서 해결해보고 찾아봐야겟어 ㅜㅜ..
https://en.wikipedia.org/wiki/Shunting-yard_algorithm