对计算器程序的改善
用链栈实现并增加三角函数、反三角函数、平方根功能
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#define STACK_INIT_SIZE 100
/*定义栈初始容量*/
#define STACK_INCREMENT 10
/*定义栈增加容量*/
#define M 100
/*定义字符串的长度*/
#define DEBUG 0
/*定义调试模式*/
typedef enum{
OK=1,
ERROR=0
}Status;
typedef enum{
TRUE=1,
FALSE=0
}Bool;
typedef struct{
void* pBase;
void* pTop;
int elementSize;
int stackSize;
}Stack;
Stack* Stack_Construct(int sizeOfElement);
/*功能:构造一个栈
*参数:栈元素类型的长度
*返回:构造成功返回新构造的栈;否则返回NULL
*/
Stack* Stack_Construct(int sizeOfElement){
Stack *pStack;
pStack=(Stack*)malloc(sizeof(Stack));
if(pStack==NULL){
return NULL;
}
pStack->pBase=malloc(STACK_INIT_SIZE*sizeOfElement);
if(pStack->pBase==NULL){
free(pStack);
return NULL;
}
pStack->pTop=pStack->pBase;
pStack->elementSize=sizeOfElement;
pStack->stackSize=STACK_INIT_SIZE;
return pStack;
}
Status Stack_Init(Stack *pStack);
/*参数:pStack是指向栈的指针
*返回:成功返回OK;否则返回ERROR
*/
void Stack_Free(Stack *pStack);
/*参数:pStack是指向栈的指针
*返回:无
*/
void Stack_Clear(Stack *pStack);
/*参数:pStack是指向栈的指针
*返回:无
*/
Bool Stack_IsEmpty(Stack *pStack);
/*参数:pStack是指向栈的指针
*返回:若栈为空,返回true;否则返回false
*/
Bool Stack_IsFull(Stack *pStack);
/*参数:pStack是指向栈的指针
*返回:若栈已满,返回true;否则返回false
*/
int Stack_Length(Stack *pStack);
/*参数:pStack是指向栈的指针
*返回:栈的长度
*/
//char Stack_GetTop(Stack *pStack);
Status Stack_GetTop(Stack *pStack,void *pElem);
/*功能:取出栈顶元素
*参数:pStack是指向栈的指针
*返回:返回栈顶元素
*/
Status Stack_Push(Stack *pStack,void *pVoid);
/*功能:将pVoid指向的数据压入pStack指向的栈
*参数:pStack是指向栈的指针,pVoid是指向数据的指针
*返回:成功返回OK;否则返回ERROR
*/
Status Stack_Pop(Stack *pStack,void *pVoid);
/*功能:将pStack指向的栈的元素弹出存入pVoid指向的内存
*参数:pStack是指向栈的指针,pVoid是指向数据的指针
*返回:成功返回OK;否则返回ERROR
*/
//Status Stack_Traverse(Stack *pStack,Status(*visit)());
/*功能:对pStack指向的栈的每个元素执行visit操作
*参数:pStack是指向栈的指针,visit是函数指针
*返回:成功返回OK;失败返回ERROR
*/
float ConvertToFloat(char m[M],float r);
/*功能:将数字串转换为浮点数
*参数:m[M]是原数字串,r是浮点数即结果
*返回:返回结果浮点数r
*/
int Judge(char x);
/*功能:判断运算符的类型并分级
*参数:x是运算符的符号
*返回:字符所代表的级数
*/
int Culculate(int x1,int x2,char s);
/*功能:执行计算
*参数:x1是第一个数字
x2是第二个数字
s是运算符
*返回:返回运算结果
*/
Status Check(char left,char right);
/*功能:判断左右括号是否匹配
*参数:left是左括号,right是右括号
*返回:若左右括号匹配返回OK,否则返回ERROR
*/
Status CharIsSymbol(char c);
/*功能:判断字符是运算符
*参数:c是字符
*返回:若c为运算符返回OK;否则返回ERROR
*/
Status CharIsNum(char d);
/*功能:判断字符是数字
*参数:d是字符
*返回:若d是数字返回OK;否则返回ERROR
*/
int DoSingleOperation(char s[]);
/*功能:执行一行字符的计算
*参数:s[]是这一行字符串
*返回:返回运算结果
*/
Status Stack_Init(Stack *pStack){
pStack->pBase=malloc(STACK_INIT_SIZE*sizeof(char));
if(pStack->pBase==NULL){
return ERROR;
}
pStack->pTop=pStack->pBase;
pStack->stackSize=STACK_INIT_SIZE;
return OK;
}
void Stack_Free(Stack *pStack){
free(pStack->pBase);
pStack->pBase=NULL;
pStack->pTop=NULL;
pStack->stackSize=0;
free(pStack);
return;
}
void Stack_Clear(Stack *pStack){
pStack->pTop=pStack->pBase;
}
Bool Stack_IsEmpty(Stack *pStack){
if(pStack->pTop==pStack->pBase){
return TRUE;
}
else{
return FALSE;
}
}
Bool Stack_IsFull(Stack *pStack){
if((char*)pStack->pTop-(char*)pStack->pBase==pStack->stackSize){
return TRUE;
}
else{
return FALSE;
}
}
int Stack_Length(Stack *pStack){
return ((char*)pStack->pTop-(char*)pStack->pBase)/pStack->elementSize;
}
Status Stack_GetTop(Stack *pStack,void *pElem){
int* pt;
char* pt2;
if(pStack->pTop==pStack->pBase){
return ERROR;
}
if(pStack->elementSize == sizeof(int))
{
pt = (int*)((char*)pStack->pTop -pStack->elementSize);
*((int*)pElem) = *pt;
}else
{
pt2 = (char*)((char*)pStack->pTop -pStack->elementSize);
*((char*)pElem) = *pt2;
}
//pElem=(char*)pStack->pTop - pStack->elementSize;
return OK;
}
Status Stack_Push(Stack *pStack,void *pElem){
int newSize;
int* pt;
char* pt2;
void *pTemp;
if(Stack_Length(pStack)>=pStack->stackSize){
newSize=pStack->stackSize+STACK_INCREMENT;
pElem=realloc(pStack->pBase,newSize*sizeof(pStack->elementSize));
if(pTemp==NULL){
return ERROR;
}
else{
pStack->pBase=pTemp;
pStack->pTop = (char*)pStack->pBase+pStack->stackSize;
pStack->stackSize=newSize;
}
}
if(pStack->elementSize == sizeof(int))
{
pt = (int*)pStack->pTop;
*pt = *((int*)pElem);
}else
{
pt2 = (char*)pStack->pTop;
*pt2 = *((char*)pElem);
}
//*(pStack->pTop)=*pElem;
#if DEBUG
printf("%d",pStack->pTop); /*调试语句*/
#endif
pStack->pTop=(char*)pStack->pTop+pStack->elementSize;
#if DEBUG
printf("%d",pStack->pTop); /*调试语句*/
#endif
return OK;
}
Status Stack_Pop(Stack *pStack,void *pElem){
if(pStack->pTop==pStack->pBase){
return ERROR;
}
else{
pStack->pTop=(char*)pStack->pTop-pStack->elementSize;
// *pElem=*(pStack->pTop);
return OK;
}
}
/*Status Stack_Traverse(Stack *pStack,Status(*visit)()){
int i,j;
j=Stack_Length(pStack);
for(i=0;i<j;i++){
if(visit(&(pStack->pBase[i]))==ERROR){
return ERROR;
}
}
return OK;
}*/
float ConvertToFloat(char m[M]){
int i=0;
float value=0;
while(m[i]!='\0'&&m[i]!='.'){
value=value*10+(m[i]-'0');
i=i+1;
}
if(m[i]=='\0'){
return value;
}
i=i+1;
int weight=0.1;
while(m[i]!='\0'){
value=value+(m[i]-'0')*weight;
weight=weight/10;
i=i+1;
}
return value;
}
int Judge(char x){
if (x == '(') {
return 4;
}
else if (x == '+' || x == '-') {
return 1;
}
else if (x == '*' || x == '/') {
return 2;
}
else if (x == '^') {
return 3;
}
else if (x == ')') {
return 0;
}
}
int Culculate(int x1,int x2,char s){
int result = 0;
switch(s){
case '+':{
result=x1+x2;
break;
}
case '-':{
result=x1-x2;
break;
}
case '*':{
result=x1*x2;
break;
}
case '/':{
result=x1/x2;
break;
}
case '^':{
result=pow((double)x1,x2);
break;
}
}
return result;
}
Status Check(char left,char right){
if(left=='('&&right==')'){
return OK;
}
else{
return ERROR;
}
}
Status CharIsSymbol(char c){
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='^'){
return OK;
}
else{
return ERROR;
}
}
Status CharIsNum(char d){
if(d>='0'&&d<='9'){
return OK;
}
else{
return ERROR;
}
}
int DoSingleOperation(char s[]){
Stack* pIntStack; /*这个栈存放数字*/
Stack* pSymbolStack; /*这个栈存放除括号外的符号*/
Stack* pSymbolStack_2; /*这个栈存放括号*/
Status sta;
pIntStack=Stack_Construct(sizeof(int));
pSymbolStack=Stack_Construct(sizeof(char));
pSymbolStack_2=Stack_Construct(sizeof(char));
int len,n;
len=strlen(s);
s[len]='#';
len++;
int i;
int a,b,c=0,d=0;
int topele_int;
char topele_c;
char x[M];
for(i=0;i<len;i++){
if(s[i]=='('){
Stack_Push(pSymbolStack_2,&s[i]);
}
else if(s[i]==')'){
Stack_GetTop(pSymbolStack_2,&topele_c);
if(Check(topele_c,s[i])==1){
Stack_Pop(pSymbolStack_2,&x[d++]);
}
else{
printf("括号不匹配\n"); /*判断括号是否匹配*/
return 0;
}
}
}
i=0;
if(s[0]=='+'||s[0]=='-'||s[0]=='*'||s[0]=='/'||s[0]=='^'){
printf("运算符不能在开头\n"); /*除括号外的运算符不能在字符串开始处*/
return 0;
}
while(s[i]!='#'){
int x=0;
if(CharIsNum(s[i])==OK){
while(s[i]>='0'&&s[i]<='9'){
x*=10;
x+=s[i++]-'0';
}
Stack_Push(pIntStack,&x);
continue;
}
else{
char theta=s[i];
while(Stack_IsEmpty(pSymbolStack)==0 ){ //&&Stack_GetTop(pSymbolStack)!='('&&Judge(Stack_GetTop(pSymbolStack))>=Judge(s[i])
Stack_GetTop(pSymbolStack,&topele_c);
if(topele_c =='(' || Judge(topele_c) < Judge(s[i]))
break;
Stack_GetTop(pIntStack,&a);
Stack_Pop(pIntStack,&topele_int); /*这里的topele_int没有用处*/
Stack_GetTop(pIntStack,&b);
Stack_Pop(pIntStack,&topele_int);
if(a==0&& topele_c =='/'){ //Stack_GetTop(pSymbolStack)
printf("除数不能为0\n"); /*判断除数是否为0,若为0则结束程序,否则继续运行*/
return 0;
}
c=Culculate(b,a,topele_c);//Stack_GetTop(pSymbolStack)
Stack_Push(pIntStack,&c);
Stack_Pop(pSymbolStack,&topele_c);
}
sta = Stack_GetTop(pSymbolStack,&topele_c);
if(sta== OK &&Judge(theta)==0&&Judge(topele_c)==4){
Stack_Pop(pSymbolStack,&topele_c);
}
if(Judge(theta)!=0){
Stack_Push(pSymbolStack,&theta);
}
i++;
}
}
while(Stack_IsEmpty(pSymbolStack)==0){
Stack_GetTop(pSymbolStack,&topele_c);
Stack_GetTop(pIntStack,&a);
Stack_Pop(pIntStack,&topele_int);
Stack_GetTop(pIntStack,&b);
Stack_Pop(pIntStack,&topele_int);
if(a==0&& topele_c=='/'){
printf("除数不能为0\n"); /*判断除数是否为0,若为0则结束程序,否则继续运行*/
return 0;
}
c=Culculate(b,a,topele_c);//Stack_GetTop(pSymbolStack)
Stack_Push(pIntStack,&c);
Stack_Pop(pSymbolStack,&topele_c);
}
Stack_GetTop(pIntStack,&a);
printf("%d\n",a);
return a;
}
//int main(){
// char all[100]={0};
// int result=0;
// FILE *fp=fopen("C:/Users/zh/Desktop/1.txt","r"); /*以只读模式打开文件1*/
// if(fp==0){
// printf("The first txt can not be opened!"); /*若打开文件1失败,结束程序,否则继续运行*/
// return 0;
// }
// FILE *fp2=fopen("C:/Users/zh/Desktop/2.txt","w"); /*以写入模式打开文件2*/
// while(!feof(fp)){
// fgets(all,100,fp); /*对文件1逐行读取*/
// int len=strlen(all);
// if(len==0){ /*若为空行,则结束此次循环,开始执行下一行的程序*/
// continue;
// }
// if(all[len-1]=='\n'){
// all[len-1]='\0';
// }
// printf("%s\n",all);
// result=DoSingleOperation(all); /*对读入的一行进行运算*/
// fprintf(fp2,"%d\n",result); /*对读入的一行的运算结果打印到文件2中*/
// }
// fclose(fp); /*关闭文件1*/
// fclose(fp2); /*关闭文件2*/
// return 0;
//}
int main(){
int i;
printf("Please choose the mode of operation\nFrom file to file:0\tFrom the keyboard:1\n");
scanf("%d",&i);
switch(i){
case 0:{
char all[M]={0};
int result=0;
FILE *fp=fopen("C:/Users/zh/Desktop/1.txt","r"); /*以只读模式打开文件1*/
if(fp==0){
printf("The first txt can not be opened!"); /*若打开文件1失败,结束程序,否则继续运行*/
return 0;
}
FILE *fp2=fopen("C:/Users/zh/Desktop/2.txt","w"); /*以写入模式打开文件2*/
while(!feof(fp)){
fgets(all,M,fp); /*对文件1逐行读取,直到文件尾*/
int len=strlen(all);
if(len==0){ /*若为空行,则结束此次循环,开始执行下一行的程序*/
continue;
}
if(all[len-1]=='\n'){
all[len-1]='\0'; /*去掉每行字符的回车符*/
}
printf("%s\n",all);
result=DoSingleOperation(all); /*对读入的一行进行运算*/
fprintf(fp2,"%d\n",result); /*对读入的一行的运算结果打印到文件2中*/
}
fclose(fp); /*关闭文件1*/
fclose(fp2); /*关闭文件2*/
break;
}
case 1:{
printf("Please input the exxpression\n");
int j=0,result;
char all[M]={0};
char y;
gets(all);
/*while((y=getchar())!='\n'){
all[j]=y;
j++;
}*/
result=DoSingleOperation(all);
printf("%d\n",result);
break;
}
default:{
printf("error number\n");
break;
}
}
return 0;
}