/* --------------------------------------------------------------------------------------
出自: 编程中国 http://www.bc-cn.net
作者: yu_hua
时间: 2007-8-10 编程论坛首发
声明: 尊重作者劳动,转载请保留本段文字
-------------------------------------------------------------------------------------- */
/*---------------------------
文本模式下利用鼠标输入
表达式的四则计算器程序
[注意]要在TC下编译连接
2007年08月09日
-----------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <conio.h>
/*鼠标的初始化函数*/
int initmouse(void)
{
union REGS regs;
regs.x.ax = 0;
int86(0x33,®s,®s);
return(regs.x.ax);
}
/*显示鼠标光标*/
void showmouse(void)
{
union REGS regs;
regs.x.ax = 1;
int86(0x33,®s,®s);
}
/*隐藏鼠标光标*/
void hidemouse(void)
{
union REGS regs;
regs.x.ax = 2;
int86(0x33,®s,®s);
}
/*查询鼠标按钮的状态及鼠标光标的x,y坐标*/
void getmouse(int *button,int *x,int *y)
{
union REGS regs;
regs.x.ax = 3;
regs.x.bx = 0;
int86(0x33,®s,®s);
*button = regs.x.bx;
*x= regs.x.cx;
*y= regs.x.dx;
}
/*设置鼠标光标的位置*/
void setmouse(int x,int y)
{
union REGS regs;
regs.x.ax = 4;
regs.x.cx = x;
regs.x.dx = y;
int86(0x33,®s,®s);
}
/*设定鼠标光标的活动范围*/
void setrange(int x1,int x2,int y1,int y2)
{
union REGS regs;
regs.x.ax = 7;
regs.x.cx = x1;
regs.x.dx = x2;
int86(0x33,®s,®s);
regs.x.ax = 8;
regs.x.cx = y1;
regs.x.dx = y2;
int86(0x33,®s,®s);
}
int main(void)
{
double calc(char*,char**);
int but,col,i,iprob,line,sta,x,y;
char src[128],s[]="0.123456789()e+-*/=\x11",*end;
if(initmouse()==0)
{
printf("Mouse not installed\n");
return(-1);
}
setrange(0,8*strlen(s)-1,0,7);/*将鼠标光标的活动范围限制在s[]元素以内*/
showmouse();/*让鼠标光标变成“可见的”*/
clrscr();
textattr(16*CYAN|BLACK);
cprintf(s);/*将提示信息s[]显示在屏幕左上方,青底黑字*/
for(sta=iprob=0,line=2;line<=25;line++)/*从第2行到第25行可连续做24道题*/
{
setmouse(0,0);/*每道题刚开始的时候,鼠标光标定位于屏幕左上角*/
gotoxy(1,line);
col=1+printf("Expression(%d): ",++iprob);/*iprob是题目的编号*/
i=0;
while(1)
{
getmouse(&but,&x,&y);/*测试鼠标按钮状态及鼠标光标的位置*/
if(but&2){hidemouse();return(1);}/*若按下鼠标右钮则退出*/
if((but&1)==0){sta=0;continue;}/*若鼠标左钮放开,则sta:=0且进入下一次循环*/
if(sta==0)/*若鼠标左钮由放开变成按下状态*/
{
char key;
sta=1;
key=s[x/8];
if(key != 0x11)
{
col+=printf("%c",key);
if(key=='=')break;
src[i++]=key;
}
else if(i)
{
col--;i--;
gotoxy(col,line);
printf(" ");/*用空格“擦除”原先的那个字符*/
gotoxy(col,line);
}
}
}
src[i]='\0';
printf("%lf",calc(src,&end));
}
hidemouse();
return(0);
}
/*-----------------------------------
calculator only for +,-,*,/
------------------------------------*/
double calc(char *epr,char **pe)
{ char op[10]={1}; int iop=1;
double ST[10]={0}; int ist=1;
char*pp=epr,*qq,ch;
pp+=strspn(pp," \t");
if(*pp=='+')op[0]=+1,pp++;else
if(*pp=='-')op[0]=-1,pp++;
do
{ int length=1;
pp+=strspn(pp," \t");
switch(ch=*pp)
{ case'\0': case'\n': case'=': case')':
op[iop++] =0; break;
case '(': ST[ist++]=calc(pp+1,pe);
length=*pe-pp;break;
case '+': op[iop++]=+1; break;
case '-': op[iop++]=-1; break;
case '*': op[iop++]=+2; break;
case '/': op[iop++]=-2; break;
default: ST[ist++]=strtod(pp,&qq);
if(qq==pp)exit(1);
length=qq-pp;break;
}
if(ist<=iop)
while(op[0])
{ char old=0,now=op[iop-1];
if(iop > 1)old=op[iop-2];
if(abs(now)>abs(old))break;
if(--ist==0)exit(2);
--iop;op[iop-1]=now;
switch(old)
{ case +1: ST[ist-1] += ST[ist]; break;
case -1: ST[ist-1] -= ST[ist]; break;
case +2: ST[ist-1] *= ST[ist]; break;
case -2: ST[ist-1] /= ST[ist]; break;
}
}
pp+=length;
}
while(ch!=')'&& ch!='='&& ch!='\n'&& ch!='\0');
*pe=pp; return ST[0];
}