⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 calc.c

📁 简单的计算器
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 
http://[2001:4860:c003::84]/search?q=cache:FSQVqd7pmq4J:www.yuanma.org/data/2007/0308/article_2390.htm+calc.c+%E8%AE%A1%E7%AE%97%E5%99%A8&hl=zh-CN&newwindow=1&strip=1
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])));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -