您的位置:首页 > 其它

四则运算计算器 C 语言完美版源码

2007-03-08 14:21 302 查看
以下是我刚开始学习 C 语言时实训的作品,感觉还不错。
有什么意见和建议,请联系我:
Email:HeTaoOS#Gmail.com
QQ:28681290

/*
Calc.c By Null 生成于 200607032000
编号:9
四则运算计算器

一、程序功能简介
可以计算整数四则运算,例如:7+5*(3+4)

二、课程设计要求
(1)按要求在提供的框架程序源程序的基础上对程序进行修改、补充,并调试通过。
(2)修改主程序结构,使程序可以反复运算,直到选择退出为止。
(3)增加文件的输入输出功能,是计算过的式子和结果可以根据需要设置命令存储到文件中,同时也可以直接从文件中输入四则运算的式子,运算后,结果输出到原文件中。
(4)扩充程序功能,使程序适合实型数运算。
(5)增加程序的判断功能,当有非法的输入时(如字母等),给出提示信息并退出运算。
(6)扩充程序功能,使程序可以进行关系表达式(>=,>,<=,<,==等)的运算,运算结果为 TRUE 或 FALSE 。

在 VC++6 环境下编译
已经完美实现上述功能
注:
包含 Debug 的语句 如:if (Debug) printf(""); 都并封装成 Ope 可以忽略,
这些显示是编写工程中需要观察的信息,如果要打开,请在主菜单下输入大写的 'D'。

Log:
20060703 开始分析框架程序,并规划程序结构
20060704 计算的核心部分基本完成,ration()
20060705 编写 Menu_Sel() Do_Press() strChk() Do_File() FileCHK() Nexus() 整体功能和界面基本完成
20060706 强化 strChk(),增加 Debug 模式,修正符号优先级问题。
20060707 郁闷,在英化程序 -_-/// ...在 Do_File() 增加输出文件另存功能...
20060708 ....
20060709 ....
20060710 强化 strChk(),增加结果整形识别,增加 '!=' 处理,文件名非法字符校验。
最后更新 20060710
*/
/* =============================================== */
/* 头文件声明 */
#include <stdio.h>  /* In Out printf().. */
#include <math.h>   /* pow(M,n) 开 M^n  */
#include <string.h>	/* strcpy... */
#include <stdlib.h>	/* atof... */
#include <conio.h>	/* getch()... */

#define Max 256     /* 表达式长度定义,可以在这里调节 */
/* =============================================== */
/* 函数声明 */

/* 计算字符串(不带括号的),计算的核心部分*/
char *Calculate_f(char *chpString);
/* 主操作过程,输入式子串,返回 double 型结果 */
double Operation(char *chpString);
/* Source1、Source2 加起来到 Destination 中*/
char *AddStrings_f(char *chpDestination, char *chpSource1, char *chpSource2);

/* 寻找 char_to_find 在 Source 中的位置,后移一位 */
int FindChar(char *chpSource, char chCharToFind);
/* 获取字符串的长度 */
int Len_f(char *chpSource);

/* 将 Source 左边 Length 个字符放在 Destination 中*/
char *Left_f(char *chpSource, char *chpDestination, int nLength);
/* 将 Source 右边 Length 个字符放在 Destination 中*/
char *Right_f(char *chpSource, char *chpDestination, int nLength) ;
/* 将 Source 中从 Start 开始 Length 长度的字符串截下来放在 Destination 中*/
char *Midstr_f(char *chpSource, char *chpDestination, int nStart, int nLength);
/* 在字符串中删除一个字符 del '+' */
void DelChar(char *chpString,int sPos);
/* 在字符串中插入一个字符 */
int InsChar(char *chpString,int sPos,char sChar);
/* 替换字符串中的某个字符 */
void StrReplace(char *chpString,char strOld ,char strNew);

/* 将实数值变为字符串*/
char *Str_f(double nValue, char *chpDestination);
/* 计算字符串的值,返回实数值 */
double Val_f(char *chpSource) ;

/* =============================================== */
/* 主菜单... */
int Menu_Sel();
/* 手工输入表达式求值 */
int Do_Press();
/* 文件导入表达式求值 */
int Do_File();
/* 文件检查 0 重新输入,1 继续 */
int FileChk(char *FN);
/* 式子的合法性检查 0 含有非法字符,1 正常 2 关系运算 */
int StrChk(char *chpSource);
/* 关系运算 */
int Nexus(char strIn[]);

/* 显示关于 */
void Show_About();
/* =============================================== */
/* 全局变量声明 */
int Debug=0;                                        /* 调试信息显示开关 0 不显示,1 显示 */
char *TF_Info[3]={"FALSE","TURE","Error"};          /* 关系运算信息 */

/* 将 Source 左边 Length 个字符放在 Destination 中*/
char *Left_f(char *chpSource, char *chpDestination, int nLength)
{
*(chpDestination+ --nLength+1)=0;               /* 设置目标字符串最后一个为 NULL*/
while (nLength>=0)                              /* 直到目标字符串的最后一个 */
{
*(chpDestination+nLength)=*(chpSource+nLength--);
}
return chpDestination;
}

/* 将 Source 中从 Start 开始 Length 长度的字符串截下来放在 Destination 中 */
char *Midstr_f(char *chpSource, char *chpDestination, int nStart, int nLength)
{
chpSource+=nStart-1;                            /* 设置源起点 */
*(chpDestination+--nLength+1)=0;                /* 设置目标字符串最后一个为 NULL */
while (nLength>=0)                              /* 直到目标字符串的最后一个 */
{
*(chpDestination+nLength)=*(chpSource+nLength--);
}
return chpDestination;
}

/* 将 Source 右边 Length 个字符放在 Destination 中 */
char *Right_f(char *chpSource, char *chpDestination, int nLength)
{
while (*chpSource != 0)
{
chpSource++;
}                                              /* 将源指针移到最后 */
chpSource-=nLength;                            /* 将源指针跳到开始复制点 */
*(chpDestination+--nLength+1)=0;               /* 设置目标字符串最后一个为 NULL */
while (nLength>=0)                             /* 直到目标字符串的最后一个 */
{
*(chpDestination+nLength)=*(chpSource+nLength--);
}
return chpDestination;
}

/* 在字符串中删除一个字符 del '+' */
void DelChar(char *chpString,int sPos)
{
char sBuf[Max];
int nCount;
strcpy(sBuf,chpString);
for(nCount=sPos;sBuf[nCount];nCount++)
{
sBuf[nCount]=sBuf[nCount+1];
}
strcpy(chpString,sBuf);
}

/* 在字符串中插入一个字符 */
int InsChar(char *chpString,int sPos,char sChar)
{
char sBuf[Max];
int iLen;
int nCount;
strcpy(sBuf,chpString);
iLen=strlen(sBuf);
if(iLen<Max)
{
sBuf[iLen+1]='/0';
for(nCount=iLen;nCount>=sPos;nCount--)
{
sBuf[nCount+1]=sBuf[nCount];
}
sBuf[sPos]=sChar;
strcpy(chpString,sBuf);
}
else
return 0;
return 1;
}

/* 替换字符串中的某个字符 '#' to '-' */
void StrReplace(char *chpString,char strOld ,char strNew)
{
char sBuf[Max];
int nCount=0;
strcpy(sBuf,chpString);
while(sBuf[nCount])
{
if (sBuf[nCount]==strOld) sBuf[nCount]=strNew;
nCount++;
}
strcpy(chpString,sBuf);
}

/* 寻找 char_to_find 在 Source 中的位置,后移一位*/
int FindChar(char *chpSource, char chCharToFind)
{
int nPos=0;
while(*(chpSource+nPos)!=0)                     /* 直到目标字符串的最后一个 */
{
if (chCharToFind == *(chpSource+nPos++))    /* 比较.. */
{
return nPos;                            /* 返回第一个出现点,加一 */
}
}
return 0;
}

/* 获取字符串的长度 */
int Len_f(char *chpSource)
{
int nRetval=0;                                  /* 初始化长度 */
while (*(chpSource+nRetval++)!=0){}             /* 移动指针到 Null */
return --nRetval;
}

/* 将实数值变为字符串*/
char *Str_f(double nValue, char *chpDestination)
{
char strTmp[Max];
gcvt(nValue,sizeof(double)+1,strTmp);           /* 实数值转字符串 */
if(strTmp[0]=='-')								/* 将 '-' 负号 转译为 '#' */
{
strTmp[0]='#';
}
strcpy(chpDestination,strTmp);
if(Debug) printf("...Conversion Double to String:%f - >%s/n",nValue,chpDestination);
return chpDestination;
}

/* Source1、Source2 加起来到 Destination 中*/
char *AddStrings_f(char *chpDestination, char *chpSource1, char *chpSource2)
{
char *chpTempdest=chpDestination;
while(*chpSource1!=0)                           /* 先把 chpSource1 放入 chpDestination */
{
*(chpTempdest++)=*(chpSource1++);
}
while(*chpSource2!=0)                           /* 在 chpDestination 后继续写入 chpSource2 */
{
*(chpTempdest++)=*(chpSource2++);
}
*chpTempdest=0;                                 /* 指针位置归零 */
return chpDestination;
}

/* 计算字符串的值,返回实数值 */
double Val_f(char *chpSource)
{
double nResult=0.;
char strTmp[Max];
strcpy(strTmp,chpSource);
if(strTmp[0]=='#')                              /* 将 '#' 转译为 '-' 负号 */
{
strTmp[0]='-';
}
nResult=atof(strTmp);                           /* 字符串转为实数 */
if(Debug) printf("...Conversion String to Double:%s -> %s -> %f/n",chpSource,strTmp,nResult);
return nResult;
}

/* 计算字符串(不带括号的),计算的核心部分*/
char *Calculate_f(char *chpString)
{
char szBuf1[Max], szBuf2[Max], szBuf3[Max], szBuf4[Max], szBuf5[Max]; /* buffers for string handlers */
char sOps[2][4]={"^*+","^/-"};                  /* 呵呵,符号优先级问题已经解决 */
double nLeftnr;                                 /* 操作符左边的结果 */
double nRightnr;                                /* 操作符右边的结果 */
double nResult;                                 /* 表达式的结果 */
int nOppos;                                     /* 操作符的位置+1 */
int nOppos2;
int nOp=0;                                  	/* 用哪一个同级的操作符 */
int nCount;                                     /* 长度计数,就是两个操作符间的内容的长度 */
int nPosInOpstr;                                /* 操作符索引 */
if(Debug) printf("/n...Starting Calculate, The Parameter is:%s/n",  chpString );

for (nPosInOpstr=0; nPosInOpstr<3; nPosInOpstr++)   /* 同级关系运算符问题,有待解决 */
{                                               /* szOpstr 中操作符的顺序就是优先级顺序 */

while (FindChar(chpString,sOps[0][nPosInOpstr])!=0||FindChar(chpString,sOps[1][nPosInOpstr])!=0)                  /* 寻找五种符号,当找不到就退出*/
{                                           /* 提取左边的操作数计算*/
nOppos=FindChar(chpString,sOps[0][nPosInOpstr]);     /* 行 0 找到操作符的位置,+1 */
nOppos2=FindChar(chpString,sOps[1][nPosInOpstr]);    /* 行 1 找到操作符的位置,+1 */
if(Debug) printf("...Operator Priority Level:nOppos=%d nOppos2=%d nOp=",nOppos,nOppos2);
if(nOppos==0)                           /* 取靠前的,0 是个问题,跳过... */
{
nOp=1;
nOppos=nOppos2;
}
else if(nOppos2==0)
{
nOp=0;
}
else if(nOppos>nOppos2)
{
nOp=1;
nOppos=nOppos2;
}
else nOp=0;
if(Debug) printf("%d/n",nOp);
for (nCount=nOppos-2;  nCount>=0; nCount--)                                 		/* 向左边查找操作符 */
{
if ((*(chpString+nCount)=='+')||(*(chpString+nCount)=='/')||(*(chpString+nCount)=='-')||(*(chpString+nCount)=='*')||(*(chpString+nCount)=='^'))
{
if ((nCount>1)&&((*(chpString+nCount-1)=='e')||(*(chpString+nCount-1)=='E')||(*(chpString+nCount-1)=='^'))) continue;       /* 注意 1e-1 等,'-' 并不是单独的操作符 */
nLeftnr=Val_f(Midstr_f(chpString,&szBuf1[0], nCount+2, nOppos-nCount-2));   /* 符号左边的字符串变为数值*/
nCount=-1;
}
else if (nCount==0)                 /* 如果从头开始复制... */
{
nLeftnr=Val_f(Left_f(chpString,&szBuf1[0],nOppos-1));
}
}
if(Debug) printf("...Left Operand:%f/n",nLeftnr);
/* 提取右边的操作数计算*/
for (nCount=nOppos;nCount<Len_f(chpString);nCount++)
{
if ((*(chpString+nCount)=='+')||(*(chpString+nCount)=='/')||(*(chpString+nCount)=='-')||(*(chpString+nCount)=='*')||(*(chpString+nCount)=='^'))
{
if ((*(chpString+nCount-1)=='e')||(*(chpString+nCount-1)=='E')||(*(chpString+nCount-1)=='^')) continue;                 /* 注意 1e-1 等,'-' 并不是单独的操作符 */
nRightnr=Val_f(Midstr_f(chpString,&szBuf2[0],nOppos+1,nCount-nOppos));      /* 符号右边的字符串变为数值*/
nCount=Len_f(chpString);
}
else if (nCount==Len_f(chpString)-1)
{
nRightnr=Val_f(Right_f(chpString,&szBuf2[0],Len_f(chpString)-nOppos));
}
}
if(Debug) printf("...Right Operand:%f/n",nRightnr);
/* 计算 */
if (sOps[nOp][nPosInOpstr]=='+')          /* 加 */
{   nResult=nLeftnr+nRightnr;   }
else if (sOps[nOp][nPosInOpstr]=='-')     /* 减 */
{   nResult=nLeftnr-nRightnr;   }
else if (sOps[nOp][nPosInOpstr]=='/')     /* 除 */
{   nResult=nLeftnr/nRightnr;   }
else if (sOps[nOp][nPosInOpstr]=='*')     /* 乘 */
{   nResult=nLeftnr*nRightnr;   }
else if (sOps[nOp][nPosInOpstr]=='^')     /* 次方/开方 */
{   nResult=pow(nLeftnr,nRightnr);}
/* 组建新的字符串 */
/* 格式AddStrings_f(目标,源1,源2) */
AddStrings_f(&szBuf3[0], Left_f(chpString,&szBuf4[0],nOppos-Len_f(&szBuf1[0])-1), Str_f(nResult,&szBuf5[0]));
AddStrings_f(chpString, &szBuf3[0],Right_f(chpString,&szBuf5[0],Len_f(chpString)-nOppos-Len_f(&szBuf2[0])));

if(Debug) printf( "...Scaning:%c,Find:%f%c%f/n...Calculate to a New String:%s/n/n",
sOps[nOp][nPosInOpstr], nLeftnr,sOps[nOp][nPosInOpstr], nRightnr,chpString );
}
}
if(Debug) printf( "...Finish Calculate, The Result is: %s/n/n", chpString);
return chpString;
}
/* 主操作过程,输入式子串,返回 double 型结果,起着移除括号的重任 */
double Operation(char *chpString)
{
char szStrn[Max],szBuf1[Max],szBuf2[Max],szBuf3[Max],szBuf4[Max];
int nCount, nLastOpen;
strcpy(szStrn,chpString);
if(Debug) printf( "/n...Starting Bracket Removal Loop.../n");
while(FindChar(&szStrn[0],'('))
{
for (nCount=0; nCount<=Len_f(&szStrn[0]); nCount++) /* 不断地查找配对的括号... */
{
if (szStrn[nCount]=='(')                /* 起始括号 */
{
nLastOpen=nCount;                   /* 最近一个'(' ,是指最接近 ')' 的那个,使之配对*/
}
if (szStrn[nCount]==')')                /* 如果最近有一个配对的括号,就进入计算 */
{                                       /* 将括号内的字符串打印出来 */
if(Debug) printf("...In %s Find %s, Calling Calculate Unit.../n",szStrn,Midstr_f(&szStrn[0],&szBuf1[0],nLastOpen+2,nCount-nLastOpen-1));

/* 将括号中的结果计算出来,连同括号左边的字符串形成新的字符串放入缓冲区,再与括号右边的字符串形成新的字符串 */
/* 复合形式...有点难看懂.. 和 Calculate_f 中的基本一样 */
AddStrings_f(&szStrn[0],AddStrings_f(&szBuf1[0],Left_f(&szStrn[0],&szBuf3[0],nLastOpen),
Calculate_f(Midstr_f(&szStrn[0],&szBuf4[0],nLastOpen+2,nCount-nLastOpen-1))),
Right_f(&szStrn[0],&szBuf2[0],Len_f(&szStrn[0])-nCount-1));

if(Debug) printf("...New String: %s/n", szStrn);
nCount=Len_f(&szStrn[0])+1;         /* 移动当前指向... */
}
}
}
if(Debug) printf("...Brackets Removed, Final String is:%s, Calculating.../n", szStrn);
/* 计算剩余的式子 */
Calculate_f(&szStrn[0]);
if (szStrn[0] == 0)
{
szStrn[0]='0';
szStrn[1]=0;
}
if(Debug) printf("...Finish Expression Calculate./n");
return Val_f(szStrn);                           /* 返回计算结果 */
}
/* 式子的合法性检查 0 含有非法字符,1 正常 2 关系运算 */
int StrChk(char *chpSource)
{
char strIn[Max];                                /* 源 */
char strTmp;                                    /* 单个字符 */
int nCount=0;
int LB=0,RB=0;                                  /* 括号计数变量 */
int nNexus=0;
int iLen;
strcpy(strIn,chpSource);
iLen=strlen(strIn);
/* 开头符号合法性检查 */
strTmp=strIn[0];
if(strTmp=='+')									/* 移除多余的 '+' */
{
DelChar(strIn,0);
iLen--;
}
if(strTmp=='*'||strTmp=='/'||strTmp=='e'||strTmp=='E'||strTmp=='^'||strTmp==')'||strTmp=='='||strTmp=='>'||strTmp=='<')
{
printf("In %s Head Find Illegal Char:%c,",strIn,strTmp);      /* 其实可以去掉非法字符在判断的... */
return 0;
}                                               /* 返回错误信息 */

/* 结尾符号合法性检查 */
strTmp=strIn[strlen(strIn)-1];
if((strTmp>='0'&&strTmp<='9')||strTmp==')');		/* 注意,有个分号的 */
else
{
printf("In %s End Find Illegal Char:%c,",strIn,strTmp);      /* 其实可以去掉非法字符在判断的... */
return 0;
}

for(nCount=0;strIn[nCount];nCount++)            /* 检查是否有非法字符 */
{
strTmp=strIn[nCount];
if((strTmp>='0'&&strTmp<='9'||strTmp=='+'||strTmp=='-'||strTmp=='*'||strTmp=='/'||strTmp=='.'||strTmp=='e'||strTmp=='E'||
strTmp=='^'||strTmp=='('||strTmp==')'||strTmp=='='||strTmp=='>'||strTmp=='<'||strTmp=='#'||strTmp=='!'))
{                                           /* 展示可能出现的字符 */
if(strTmp=='='||strTmp=='>'||strTmp=='<'||strTmp=='!')
{										/* 检查关系操作符 */
if(strTmp!='!')						/* != 检查,这样不利于以后的拓展 */
{
nNexus=1;						/* Pass */
}
else
{
if (strIn[nCount+1]!='=')
{
printf("In %s Find /'!/',But The Next Char NOT /'=/',",strIn);
return 0;
}
else if (strIn[nCount-1]=='='||strIn[nCount-1]=='>'||strIn[nCount-1]=='<')
{
printf("In %s Find /'!/',But The Previous Char IS /'%c/',",strIn,strIn[nCount-1]);
return 0;
}
}
}
continue;
}
printf("In %s Find Illegal Char:%c,",strIn,strTmp);          /* 其实可以去掉非法字符在判断的... */
return 0;                                   /* 返回错误信息 */
}

/* 表达式的修复处理 */
for(nCount=0;strIn[nCount];nCount++)
{
strTmp=strIn[nCount];                       /* 括号修复 */
if(strTmp=='('||strTmp==')')
{
if (strTmp=='(') LB++;
else RB++;
if(LB<RB)
{
InsChar(strIn,0,'(');
LB++;
nCount++;
iLen++;
if(Debug) printf("...Add a Left Bracket./n");
}
}
}
LB=0; RB=0;										/* 复位很重要,或者重新定义 */
for(nCount=0;strIn[nCount];nCount++)
{
strTmp=strIn[nCount];                       /* 括号计数 */
if(strTmp=='(') LB++;
if(strTmp==')') RB++;
}

if (LB!=RB)                                     /* 判断括号的对称性 */
{
if(abs(LB-RB)<Max-iLen)						/* 添加括号前,判断是否会越界 */
{
if(LB>RB)               				/* 右括号配对 */
{
for(nCount=0;nCount<LB-RB;nCount++)
{
InsChar(strIn,iLen,')');        /* 在最右边插入 ')' */
iLen++;
}
if(Debug) printf("...The Result of Right Bracket Partnership:%s/n",strIn);
}
else if(LB<RB)              			/* 左括号配对 */
{
for(nCount=0;nCount<RB-LB;nCount++)
{
InsChar(strIn,0,'(');           /* 在最左边插入 '(' */
}
if(Debug) printf("...The Result of Left Bracket Partnership:%s/n",strIn);
}
}
else
{
printf("Bracket NOT Partnership:%s/n",strIn);
return 0;
}
}

/* 补上 '(' 前的 '*' 以及处理后一个非法字符*/
for(nCount=1;strIn[nCount];nCount++)
{

if (strIn[nCount]=='(')
{
strTmp=strIn[nCount+1];					/* 取后一个字符 */
if(strTmp=='*'||strTmp=='/'||strTmp=='e'||strTmp=='E'||strTmp=='^'||strTmp=='<'||strTmp=='>'||strTmp=='='||strTmp==')')
{
printf("Find Err Operator In:%s,",strIn);
return 0;
}

strTmp=strIn[nCount-1];					/* 取前一个字符 */
if(strTmp>='0'&&strTmp<='9'||strTmp==')')
{
InsChar(strIn,nCount,'*');
nCount++;
if(Debug) printf("...The Result of Plus Operator /'*/':%s/n",strIn);
}

}
}
/* 补上 ')' 后的 '*' */
for(nCount=1;strIn[nCount];nCount++)
{

if (strIn[nCount]==')')
{
strTmp=strIn[nCount-1];					/* 取前一个字符 */
if(strTmp=='*'||strTmp=='/'||strTmp=='e'||strTmp=='E'||strTmp=='^'||strTmp=='<'||strTmp=='>'||strTmp=='='||strTmp=='(')
{
printf("Find Err Operator In:%s,",strIn);
return 0;
}

strTmp=strIn[nCount+1];					/* 取后一个字符 */
if(strTmp>='0'&&strTmp<='9'||strTmp=='(')
{
InsChar(strIn,nCount,'*');
nCount++;
if(Debug) printf("...The Result of Add Operator /'*/':%s/n",strIn);
}

}
}
/* 移除多余的 '+' */
for(nCount=1;strIn[nCount];nCount++)
{
if (strIn[nCount]=='+')
{
strTmp=strIn[nCount-1];                 /* 取前一个字符,如果是下列字符,这判正号 */
if(strTmp=='+'||strTmp=='-'||strTmp=='*'||strTmp=='/'||strTmp=='e'||strTmp=='E'||strTmp=='^'||strTmp=='('||strTmp=='<'||strTmp=='>'||strTmp=='=')
{
DelChar(strIn,nCount);
iLen--;
if(Debug) printf("...The Result of Conversion Add /'+/' to /'0/':%s/n",strIn);
strTmp=strIn[nCount+1];				/* 取后一个字符,过滤三重字符 -Plus*/
if(strTmp=='+'||strTmp=='-'||strTmp=='*'||strTmp=='/'||strTmp=='e'||strTmp=='E'||strTmp=='^'||strTmp=='('||strTmp=='<'||strTmp=='>'||strTmp=='=')
{
printf("Have Overmany Operator In:%s,",strIn);
return 0;
}
}
}
}

/* 将 '-' 负号替换为 '#' */
if(strIn[0]=='-') strIn[0]='#';
for(nCount=1;strIn[nCount];nCount++)
{
if (strIn[nCount]=='-')
{
strTmp=strIn[nCount-1];                 /* 取前一个字符,如果是下列字符,这判负号 */
if(strTmp=='+'||strTmp=='-'||strTmp=='*'||strTmp=='/'||strTmp=='e'||strTmp=='E'||strTmp=='^'||strTmp=='('||strTmp=='<'||strTmp=='>'||strTmp=='=')
{
strIn[nCount]='#';
if(Debug) printf("...The Result of Conversion Minus /'-/' to /'#/':%s/n",strIn);

strTmp=strIn[nCount+1];				/* 取后一个字符,过滤三重字符 -Plus*/
if(strTmp=='+'||strTmp=='-'||strTmp=='*'||strTmp=='/'||strTmp=='e'||strTmp=='E'||strTmp=='^'||strTmp=='('||strTmp=='<'||strTmp=='>'||strTmp=='=')
{
printf("Have Overmany Operator In:%s,",strIn);
return 0;
}
}
}
}
/* 重叠符号检查 */
for(nCount=1;strIn[nCount];nCount++)
{
strTmp=strIn[nCount];
if (strTmp=='+'||strTmp=='-'||strTmp=='*'||strTmp=='/'||strTmp=='^')
{
strTmp=strIn[nCount+1];                 /* 取前一个字符,如果是下列字符,这判负号 */
if(strTmp=='+'||strTmp=='-'||strTmp=='*'||strTmp=='/'||strTmp=='^')
{
printf("Find Double Operator %c and %c,",strIn[nCount],strTmp);
return 0;
}
}
}

strcpy(chpSource,strIn);
return 1+nNexus;                                /* 通过合法检查 */
}

/* 传说中的主函数 */
int main(int argc, char *argv[])
{
Debug=0;                                		/* Debug 调试开关 */
if (argc>1)										/* 调试信息显示开关 */
{
Debug=!strcmp("/debug",argv[1]);            /* 设置调试开关参数为 /debug */
if(Debug)
{
system("cls");
printf("/n/t/t/t/t    == NOTE ==/n");
printf("/t/t      * Debugging Information Has Opened */n");
printf("/t * These Messages Primarily to the Process of Debugging Phase */n");
printf("/t* This Information Reflects the Detailed Process of Calculating */n");
printf("/t/t/t/t     * NULL */n");
printf("/n");
}
}
for(;;)
{
switch (Menu_Sel())                         /* 返回选择的项目序号 */
{
case 0: case -21:case 'E'-'0': case 'e'-'0':
case 'X'-'0': case 'x'-'0':     		/* 退出 */
printf("/n/n/t/t      Thank You Use ^_^ .../n");
getch();
return 0;
case 1: case 'P'-'0': case 'p'-'0':         /* 手工输入 */
Do_Press();
break;
case 2: case 'L'-'0': case 'l'-'0':         /* 导入文件 */
Do_File();
break;
case 3: case 'C'-'0': case 'c'-'0':         /* 清屏 */
system("cls");
break;
case 4: case 'A'-'0': case 'a'-'0':         /* 显示关于 */
Show_About();
break;
case 20:                                    /* 调试信息显示控制开关,隐藏的 */
if(Debug)                       		/* 由大写的字母 'D' */
{
printf("/n/n/t************   Debugging Information Are Closed   ************/n/n");
Debug=0;
}
else
{
printf("/n/n/t************   Debugging Information Has Opened   ************/n/n");
Debug=1;
}
}
}
}

/* 显示关于 */
void Show_About()
{
system("cls");
printf("/n/t/t/t  Expression Calculator V0.2/n");
printf("/n/tFunctional Profiles:/n");
printf("/t1.Support Real-Mathematical Operations,ect.:7+5(3^-1+4)*(1+9.44/n");
printf("/t2.Support Relations Operations,ect.:4+8.45>=3456.1234+233^-2.94/n");
printf("/t3.Support Save the Expression and Results to File/n");
printf("/t4.Support Load Expression for Calculate From File/n");
printf("/t5.Support Humanization Guide Mode/n");
printf("/t----------------------------------------------------/n");
printf("/n/tProgrammer:He Tao  ID:0505030321  Nickname:Null/n");
printf("/n/tFor Further Suggestions and Comments, Please Contact/n");
printf("/tEmail:HeTaoOS@Gmail.com  QQ:28681290/n");
printf("/tWelcome to Visit/n");
printf("/thttp://HeTaoOS.GooglePages.com/n");
printf("/thttp://Blog.VeryCD.com/hetaoos/n");
printf("/t----------------------------------------------------/n");
getch();
}

/* 显示主菜单... */
int Menu_Sel()
{
char Sel;
int MaxItem=4;
printf("/n/t/t             Expression Calculator/n");
printf("/t/t      ===================================/n");
printf("/t/t      |  1.[P]ress an Expression        |/n");
printf("/t/t      |  2.[L]oad Expression From File  |/n");
printf("/t/t      |  -----------------------------  |/n");
printf("/t/t      |  3.[C]lear Screen               |/n");
printf("/t/t      |  4.[A]bout ME                   |/n");
printf("/t/t      |  0.[E]xit                       |/n");
printf("/t/t      ===================================/n");
printf("/t/t      Press a Key to Continue(0-%d):",MaxItem);
for (;;)
{
Sel=getch();
if ((Sel<'0'||Sel>MaxItem+'0')&&Sel!='D'&&Sel!='P'&&Sel!='p'&&Sel!='L'&&Sel!='l'&&Sel!='C'&&Sel!='c'&&
Sel!='A'&&Sel!='a'&&Sel!='E'&&Sel!='e'&&Sel!='X'&&Sel!='x'&&Sel!=27)
{                               			/* 输入范围检查 */
printf("/n/t/t      Press Error! Please Retry(0-%d):",MaxItem);
}
else
break;
}
return Sel-'0';
}

/* 手工输入表达式求值 */
int Do_Press()
{
char sel;
int WF=0;                                       /* 文件写入开关 */
char FN[256];                                   /* 文件名 */
char strExp[Max];                               /* 要计算的表达式 */
double strRes;                                  /* 计算结果 */
int TF=0;                                       /* 真假判断 */
int strChk_Re=0;
FILE *fp;
printf("/nWhether Save The Expression and Result to File(Y/N)?");
scanf("%s",&sel);                               /* 保存到文件 */
if(sel=='Y'||sel=='y')
{
WF=1;
for(;;)
{
printf("Press a File Name for Save Log(Press /'`/' to Exit):");
scanf("%s",FN);
if(FN[0]=='`')                          /* 设置取消陷阱 */
{
WF=0;
printf("/nYou Cancelled Save Log Operation!/n");
break;
}
if (FileChk(FN))                        /* 文件检查 */
{
fp=fopen(FN,"a");
break;
}
}
}
for(;;)
{
printf("Please Press an Expression(Press a /'`/' to Exit):/n");
scanf("%s",strExp);
if(strExp[0]=='`') break;                   /* 设置取消陷阱 */
strChk_Re=StrChk(strExp);
if(strChk_Re==0)                        	/* 错误退出 */
{
printf("NO Activate Calculation.../n");
}
else if(strChk_Re==1)                       /* 表达式计算 */
{
strRes=Operation(strExp);
StrReplace(strExp,'#','-');
if((long int)strRes==strRes)			/* 呵呵,去掉小数点 */
{
if(Debug) printf("...Conversion Double to Long Int./n");
printf("/n%s=%ld/n",strExp,(long int)strRes);
if(WF) fprintf(fp,"%s=%ld/n",strExp,(long int)strRes);
}
else
{
printf("/n%s=%f/n",strExp,strRes);
if(WF) fprintf(fp,"%s=%f/n",strExp,strRes);
}
}
else                                        /* 表达式关系判断 */
{
TF=Nexus(strExp);                       /* 调用判断函数判断 */
StrReplace(strExp,'#','-');
printf("/n%s --> %s/n",strExp,TF_Info[TF]);
if(WF) fprintf(fp,"%s --> %s/n",strExp,TF_Info[TF]);
}
getch();
}
if(WF) fclose(fp);
return 0;
}

/* 文件导入表达式求值 */
int Do_File()
{
char iFN[256];                                  /* 输入文件名 */
char oFN[256];                                  /* 临时文件名 */
FILE *ifp,*ofp;
double strRes;                                  /* 计算结果 */
char strExp[Max];                               /* 读取的字符串,也就是要计算的字符串 */
int TF=0;										/* TRUE FALSE Error 索引*/
int OutOther=0;									/* 输出到其它文件开关 */
int strChk_Re;
for(;;)
{
printf("/nPlease Press a File Name to Open(Press a /'`/' to Exit):/n");  /* 输入要打开的文件名 */
scanf("%s",iFN);
if(iFN[0]=='`') return 0;
ifp=fopen(iFN,"r");
if(ifp==0)                                  /* 文件存在检查 */
{
printf("File %s NOT Exist or Open Error!/n",iFN);
}
else break;
}
for(;;)
{
printf("/nPlease Press a File Name To Save(Press a /'`/' to Save to %s):/n",iFN);  /* 输入要打开的文件名 */
scanf("%s",oFN);
if(oFN[0]=='`')
{
strcpy(oFN,iFN);						/* 临时文件名,以及打开它 */
strcat(oFN,".null");
ofp=fopen(oFN,"w");
OutOther=0;
break;
}
else
{
if (FileChk(oFN))
{
ofp=fopen(oFN,"a");
OutOther=1;
break;
}
}
}

while(feof(ifp)==0)                             /* 如果没有读到文件尾 */
{
fscanf(ifp,"%s/n",strExp);                  /* 逐行读取文件内容 */
strChk_Re=StrChk(strExp);
if(strChk_Re==0)                        	/* 合法性检查 */
{
printf("Fall Across Illegal Char.../n");
fprintf(ofp,"%s Include Illegal Char, Can't Calculate!/n",strExp);
}
else if(strChk_Re==1)                       /* 表达式计算 */
{
strRes=Operation(strExp);               /* 计算 */
StrReplace(strExp,'#','-');
if((long int)strRes==strRes)			/* 呵呵,去掉小数点及其后的 '0'  */
{
if(Debug) printf("...Conversion Double to Long Int./n");
printf("/n%s=%ld/n",strExp,(long int)strRes);
fprintf(ofp,"%s=%ld/n",strExp,(long int)strRes);
}
else
{
printf("/n%s=%f/n",strExp,strRes);      /* 屏幕打印 */
fprintf(ofp,"%s=%f/n",strExp,strRes);   /* 打印输出到文件 */
}
}
else                                        /* 表达式关系判断 */
{
TF=Nexus(strExp);
StrReplace(strExp,'#','-');
printf("/n%s --> %s/n",strExp,TF_Info[TF]);
fprintf(ofp,"%s --> %s/n",strExp,TF_Info[TF]);

}
}
fclose(ifp);                                    /* 关闭文件 */
fclose(ofp);

if(OutOther)
{
printf("/nFile %s Operation Completed and The Result Save to %s.../n",iFN,oFN);
}
else
{
remove(iFN);                                /* 删除文件 */
rename(oFN,iFN);							/* 重命名文件 int rename(const char *oldname, const char *newname); */
printf("/nFile %s Operation Completed.../n",iFN);
}

getch();
return 0;
}

/* 文件检查 0 重新输入,1 继续 */
int FileChk(char FN[])
{
FILE *fp;
char sel;
int nCount=0;
for(;FN[nCount];nCount++)						/* 文件名合法检查 '/' 不好过滤...*/
{
if(FN[nCount]=='/'||FN[nCount]==':'||FN[nCount]=='*'||FN[nCount]=='?'||FN[nCount]=='/"'||FN[nCount]=='<'||FN[nCount]=='>'||FN[nCount]=='|')
{
printf("File Name %s Include Illegal Char /'%c/',Please Press a New One!/n",FN,FN[nCount]);
return 0;
}
}

fp=fopen(FN,"r");
if(fp==0)                               		/* 文件存在检查 */
{
fp=fopen(FN,"w");                       	/* 创建文件 */
if(fp==0)                       			/* 创建检查 */
{
printf("File %s Create Failure!/n",FN);
return 0;                           	/* 不可修复错误 */
}
fclose(fp);
return 1;                       			/* 成功提示 */
}
fclose(fp);

printf("File %s Already Exist,Rewrite or Cancel or Append(Y/N/A)?",FN); /* 文件存在了... */
scanf("%s",&sel);
if(sel=='Y'||sel=='y')                  		/* 覆盖 */
{
fp=fopen(FN,"w");                       	/* 覆盖检查 */
if(fp==0)
{
printf("File %s Rewrite Failure!/n",FN);
return 0;
}
fclose(fp);
return 1;
}
else if(sel=='A'||sel=='a')                     /* 允许追加 */
{
return 1;
}
else                        					/* 返回... */
{
return 0;
}
}
/* 关系运算 */
int Nexus(char strIn[])
{
int nCount=0;                                   /* 循环索引 '>'=1 '<'=2 '='=4 '!'=8 */
char strTmp;
char strBuf[Max];
int iNexus=0;                                   /* 符号代码 */
double strRes1;                                 /* 分步结果 */
double strRes2;                                 /* 符号代码 */
for(;strIn[nCount];nCount++)
{
strTmp=strIn[nCount];
if(strTmp=='>'||strTmp=='<'||strTmp=='='||strTmp=='!')
{
Left_f(strIn,strBuf,nCount);            /* 提取字符串 */
if(StrChk(strBuf)!=1)					/* 二次检查 */
{
iNexus=0;
break;
}
strRes1=Operation(strBuf);              /* 存储结果 */

iNexus=0;                               /* 初始化符号代码 */
if(strTmp=='>') iNexus++;               /* 符号代码调整 */
else if(strTmp=='<') iNexus+=2;
else if(strTmp=='=') iNexus+=4;
else iNexus+=8;

strTmp=strIn[nCount+1];                 /* 取下一个字符 */
if(strTmp=='>'||strTmp=='<'||strTmp=='=')
{                                       /* 符号代码调整 */
if(strTmp=='>') iNexus++;
else if(strTmp=='<') iNexus+=2;
else iNexus+=4;
nCount++;                           /* 移动索引号 */
}
Right_f(strIn,strBuf,strlen(strIn)-nCount-1);
if(StrChk(strBuf)!=1)					/* 二次检查 */
{
iNexus=0;
break;
}
strRes2=Operation(strBuf);
break;
}
}
switch(iNexus)                          		/* 关系比较 */
{
case 1:                                         /* > */
if(strRes1>strRes2) return 1;
else return 0;
case 2:                                         /* < */
if(strRes1<strRes2) return 1;
else return 0;
case 4: case 8:									/* =,== */
if(strRes1==strRes2) return 1;
else return 0;
case 3: case 12:                                /* <> != */
if(strRes1!=strRes2) return 1;
else return 0;
case 5:                                         /* >= */
if(strRes1>=strRes2) return 1;
else return 0;
case 6:                                         /* <= */
if(strRes1<=strRes2) return 1;
else return 0;
default:										/* 出错,唉,如果发现多组关系运算符就... */
return 2;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: