c语言实现袖珍计算器

大一无聊,只学了c,没学数据结构之类的东西。所以就裸写了个C语言控制台的小计算器。

1、支持加减乘除、括号输入

2、支持整数、浮点数。

2、支持空格输入

3、支持括号前省略乘号

目前错误输入还有待完善,但功能绝对没问题。

没有涉及堆栈知识(没学)。

#include"stdio.h"
#include"windows.h"
#include"ctype.h"
#define N 200

int t2f = -1;//判断字符,用在输入
int end,testResult,doit;
int leftBracket,rightBracket;
double numEntered[N];
char operatorEnter[N],operatorCopy[N];
const char legalCharacter[9]={'\0','+','-','*','/','(',')','='};
const double max = 10E16;
int record_bracket[N]={0,0};/**记录原始式子中,记录一对括号的位置。
                                 *下标为右括号位置。下标对应的成员为左括号位置*/

double calculateTwoNumbers(char c,double n1,double n2)
{
    double r=0.0;
    switch(c)
    {
        case'*':
            r=n1*n2;
            break;
        case'/':
            r=n1/n2;
            break;
    }
return r;
}

/**初始化各数组、变量*/
void initialize()
{
    int i;
                                   //默认输入的东西也包围在一个括号里
    for(i=0;i<N;i++)
    {
        operatorEnter[i]='\0';
        operatorCopy[i]='\0';
        numEntered[i]=0;      //字符数组初始化
        record_bracket[i]=0;
    }
    operatorEnter[0]='(';
    end = 0;
    testResult = 0;
    doit = 0;
    leftBracket = 0;
    rightBracket = 0;
    printf("\n 请输入计算式:\n\t");
}

//输入函数,输入正常完成返回一个数组长度的正值,停止字符返回-1,超规格返回-2
int input()
{
    int i,j;
    char c;
    for(i=1;i<N;i++)
    {
        c = getchar();
        if(c != '\n')
        {
            if(isdigit(c)!= 0)
            {
                ungetc(c,stdin);//将c退回标准输入流中
                scanf("%lf",&numEntered[i]);
            }
            else
            {
                operatorEnter[i] = c;
            }
        }
        else
            break;

        if(operatorEnter[i]=='#')  //停止字符的检查;
            return -1;

        if(i+1 >= N)
        {
            while(getchar()!='\n') ;//超规格输入的返回提示
            return -2;
        }

        if((operatorEnter[i]=='='))
        {
            while(j=getchar()!='\n')
                if(t2f==-1)
                    t2f = j;//判断等号后有无字符
            break;
        }
    }
    return i;
}

//检查合法性的函数,返回0就含failure,返回1就pass,
int testLegalityOfEnteredChar()
{
    int i, j;
    for(i=0;i<end;i++)
    {
        for(j=0;j<9;j++)
        {
            if(operatorEnter[i]==legalCharacter[j]){break;}
        }

        if(j>=8)
        {
            return 0;
        }
        else
        {
            operatorCopy[i]=operatorEnter[i];
        }
    }
    return 1;
}

//删除空格
void deleteSpace()
{
    int i;int j;
    for(i = end; i >= 0;i--)
    {
        if(operatorEnter[i] == 32)
        {
            for(j = i;j < end;j++)
            {
                operatorEnter[j] = operatorEnter[j+1];
                numEntered[j] = numEntered[j+1];
            }
            end--;
        }
    }
}

//添加省略掉的乘号
void addMultiplySign()
{
    for(int i =end-1;i > 0;i--)
    {
        //如果numEntered[i]存有输入的数,那么operatorEnter[i]= '\0';
        if((operatorEnter[i]=='\0'&&operatorEnter[i-1]==')')||
            (operatorEnter[i]=='('&&operatorEnter[i-1]=='\0')||
             (operatorEnter[i]=='('&&operatorEnter[i-1]==')'))
        {
            for(int j = end ; j >= i ; j--)
            {
                operatorEnter[j+1]=operatorEnter[j];
                numEntered[j+1] = numEntered[j];
                numEntered[j] = 0;
            }
            operatorEnter[i] = '*';
            end++;
        }
    }
}

/**处理空格,和数字与括号间无符号的更正处理情况,给它添加乘号。*/
void editFormat()
{
   deleteSpace();
   addMultiplySign();
}

//打印数组
void printArrays(char operatorEnter[N],double numEntered[N])
{
    for(int i = 0;i <= end;i++)
    {
        printf("operatorEnter[%d] = %c     @%d\n",i,operatorEnter[i],operatorEnter[i]);
        printf("  numEntered[%d] =%lf \n",i,numEntered[i]);
        printf("-------------\n");
    }
}

void findRightBrackets()
{
    for(int a=leftBracket;a<=rightBracket;a++)//从左括号的位置向右检测右括号
    {
        if(operatorEnter[a]==')')
        { //此步条件不成立则rightBracket=end
            rightBracket=a;
            record_bracket[a]=leftBracket;       //记录右括号对应的左括号位置
            operatorEnter[a]='\0';             //完成记录后消去当前检测到的括号
            break;
        }
    }  /**当前括号位置为operatorEnter[leftBracket],operatorEnter[rightBracket] */


}
//计算乘除法,若除数为零返回-1.
int MultiplicationAndDivision()
{
/**从右到左、检测括号里乘除号*/
    for(int b=rightBracket;b>=leftBracket;b--)
    {
        if(operatorEnter[b]=='*'||operatorEnter[b]=='/')
        {
            if(operatorEnter[b]=='/'&&numEntered[b+1]==0)
            {
                return -1;
            }
                                                                  /*测试用*///printf("\n当前符号位置为位置为%d\n",b);
            if(operatorCopy[b-1]==')')
            {//这里是为了考虑三个以上括号间乘法的问题
                int d=record_bracket[b-1];
                numEntered[d]=calculateTwoNumbers(operatorEnter[b],numEntered[d],numEntered[b+1]);
                numEntered[b+1]=0;                                 // printf("\n此次%c运算结果为%lf\n",operatorEnter[b],numEntered[d]);//测试用*/
                operatorEnter[b]='\0';      //消去乘除号
            }
            else
            {
                numEntered[b-1]=calculateTwoNumbers(operatorEnter[b],numEntered[b-1],numEntered[b+1]);
                numEntered[b+1]=0;                                 //printf("\n此次%c运算结果为%lf\n",operatorEnter[b],numEntered[b-1]);
                operatorEnter[b]='\0';      //消去乘除号
            }
        }
    }
    return 1;
}
//减法
void subtraction()
{
    for(int c=rightBracket;c>=leftBracket+1;c--)
    {
        if(operatorEnter[c]=='-')
        {                                                       // /*测试用*/printf("减号位于ch[%d]",c);
            numEntered[c+1]=(-1)*numEntered[c+1];
            operatorEnter[c]='\0';
        }
    }
}
//括号内所有数的和
void sum()
{
    for(int a=leftBracket;a<=rightBracket;a++)
    {
        numEntered[leftBracket]+=numEntered[a];
        numEntered[a]=0.0;                                             /*测试用*//*printf("\nn[%d]===%lf\n",a,numEntered[a]);*/
    }
}
//分析计算所输入式子的函数,结果存于numEntered[0],除数为0返回0;
int calculate(){
/*
从右到左检测运算符号,
每次运算结果存于numEntered[]左括号对应位置。
*/
    int j,temp=0;

    for(int i=end;i>=0;i--)//
    {

        rightBracket=end; //初始化右括号的位置在最后

        if(operatorEnter[i]=='(')
        {
           leftBracket=i;
           operatorEnter[i]='\0';//记录后消去括号

           findRightBrackets();

           temp = MultiplicationAndDivision();//计算括号内的所有乘除法
           if(temp<0) return 0;//除数为0

           subtraction();//减法
           sum();//括号内容总和
        }
 }
return 1;
}

//信息提示框
void messege_Box(int n)
{
    switch(n)
    {
        case 1:

            break;
        case 2:
            MessageBox( NULL, "您的输入含有非法字符,请检查", "错误", MB_OK  | MB_ICONINFORMATION );
            printf(" 错误:您的输入含有非法字符,请检查!\n");
            break;
        case 3:
            MessageBox( NULL, "抱歉,您所输入除数无意义", "错误!", MB_OK  | MB_ICONINFORMATION );
            printf(" 错误:抱歉,您所输入除数无意义。\n");
            break;
        case 4:
            MessageBox( NULL, "十分抱歉,错误原因未知,\n联系QQ1462468257\n在此再次向您致以诚挚的抱歉\n", "error", 0 );
            break;
        case 5:
            MessageBox( NULL, "该输入数据过大,不能保证其计算结果的正确性", "注意!", MB_OK  | MB_ICONINFORMATION );
            printf(" 注意:该输入数据过大,不能保证其计算结果的正确性.\n");
            break;
        case 6:
            MessageBox( NULL, "输入不能超过200个字符\n请重新输入", "警告!", MB_OK  | MB_ICONINFORMATION );
            printf(" 警告:输入不能超过200个字符!\n请重新输入!");
    }


}
void printTitle()
{
    printf(" ---------------四则运算计算器--------------\t\n"
           "\n 注:\t1.所有符号输入必须为英文\t\n\t2.等于号回车键结束输入\t\n"
           "\t3.输入“#”回车结束运行\n"
           "\n -------------------------------------------\n");
}

//无聊玩玩,这个没啥用
void endProgram(void)
{
    int i;
    for(i=1;i<15;i=i+3)
    {
        printf(".");
        Sleep(i*100);
    }
    printf("程序结束\n");
    Sleep(500);
}


int main(){

    printTitle();

    while(1){

        initialize();//初始化

        end=input();//输入
        if(end == -1)
        {
            endProgram();
            break;
        }
        else if(end == -2)
        {
            messege_Box(6);
            continue;
        }

        editFormat();//修正输入格式
        //printArrays(operatorEnter,numEntered);

        testResult=testLegalityOfEnteredChar();//检查输入合法性
        if(testResult!=1)
        {
            messege_Box(2);
            continue;
        }

        doit=calculate();//计算

        if(doit==1)//输出部分
        {
            printf("\t--------\n 结果为\t%lf\n",numEntered[0]);
            if(t2f != -1)
            {
                printf("注意:您的输入等号后不为空,该计算结果仅为等号前式子的计算值\n");
                t2f = -1;
            }
        }
        else if(doit==0)
        {
            messege_Box(3);
            continue;
        }
        else
        {
            messege_Box(4);
            break;
        }

        if(numEntered[0] > max)
            messege_Box(5);
        printf("\n ----------------LITTLEKIDS8----------------\n\n");
    }
return 0;
}


  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值