小学期有个程序设计,我就写了个这个交上去了,当时起名1.0,想着暑假要写个界面。现在复习delphi了,想着这玩意不值钱,索性就开了吧。。。众神也就当个笑话看看。ps:有玩win32api的高手,跪求提携。
/*
Name: Calculator Beta 1.0;
Author: Welcome.Z;
Date: 01/07/12 15:46;
Description: for calculate a sort of math expressions.
*/
#include<iostream>
#include<string>
#include<fstream>
#include<cmath>
#include<iomanip>
#include<stack>
#include<windows.h>
#include<conio.h>
#include<ctype.h>
#include<time.h>
using namespace std;
const char op2[]={'+','-','*','/','^','(',')','\0'};
const string op1[]={"sin","cos","tan","log","ln","exp","sqrt",
"abs","asin","acos","atan","sinh","cosh","tanh"};
const int priortable[8][8]={{1,1,-1,-1,-1,-1,1,1},
{1,1,-1,-1,-1,-1,1,1},
{1,1,1,1,-1,-1,1,1},
{1,1,1,1,-1,-1,1,1},
{1,1,1,1,-1,-1,1,1},
{-1,-1,-1,-1,-1,-1,1,1},
{1,1,1,1,1,2,1,1},
{-1,-1,-1,-1,-1,-1,2,1}};
bool err;
string err_info;
string copyrightname(const char *s)
{
int i=strlen(s)-1;
while (s [i]!='.') i--;
string u;
while (s [--i]!='\\') /
u = char(tolower(s[i]))+u;
return u;
}
int GetOrder(char c)
{
int m = 8;
for (int i=0;i<8;i++)
if (c==op2[i])
{
m = i;
break;
}
return m;
}
int CheckChar(char c)
{
if (('0'<=c) && (c<='9') || (c=='.'))
return 0;
else if (GetOrder(c)!=8)
return 1;
else if (('a'<=c)&&(c<='z') || ('A'<=c)&&(c<='Z'))
return 2;
else
return-1;
}
int Priority(char o1, char o2)
{
int i, j;
i = GetOrder(o1);
j = GetOrder(o2);
return priortable[i][j];
}
void transform(string mid, char *suffix)
{
int i, j;
i = 0;
j = 0;
char c = mid[0];
stack<char> S;
char o; //current operator
S.push('\0');
while(!S.empty())
{
if (CheckChar(c)==0)
{
suffix[i++] = c;
}
else if (CheckChar(c)==2)
{
suffix[i++] = c;
if(mid[j+1]=='(')
{
S.push('@');
suffix[i++] = '(';
}
}
else
{
if (i>0 && suffix[i-1]!=' ')
suffix[i++] = ' ';
switch(c)
{
case'(': S.push(c); break;
case')': o = S.top();
bool flag;
flag = false;
while (o!='(')
{
suffix[i++] = o;
suffix[i++] = ' ';
S.pop();
o = S.top();
flag = true;
}
if (flag) i--;
S.pop();
o = S.top();
if (o=='@')
{
suffix[i++] = ')';
S.pop();
}
break;
default: while(!S.empty())
{
o = S.top();
if (Priority(o,c)==1)
{
suffix[i++] = o;
suffix[i++] = ' ';
}
else break;
S.pop();
}
if (c!='\0')
S.push(c);
break;
}
}
if (c!='\0')
c = mid[++j];
}
suffix[i] = '\0';
}
double calculate(double a, char c, double b)
{
switch(c)
{
case'+': return a + b;
case'-': return a - b;
case'*': if (log10(a)+log10(b)>98)
{
err = false;
err_info = "Multiplication Overflow...";
break;
}
else
return a * b;
case'/': if (b==0)
{
err = false;
err_info = "Division By Zero...";
break;
}
else
return a / b;
case'^': bool flag;
flag = true;
if (a<0)
{
flag = false;
a = -a;
}
double m;
double x;
x = b * log10(a);
if (x>99)
{
err = false;
err_info = "Power Over flow...";
break;
}
else
{
m = exp(b * log(a));
if (!flag)
if (long(b*1000)%2==0) m = -m;
return m;
}
default: return-1;
}
}
double calc(double a, string f)
{
int i, j;
for (i=0;i<14;i++)
if (op1[i]==f) break;
switch(i)
{
case 0: return sin(a);
case 1: return cos(a);
case 2: return tan(a);
case 3: if (a<0)
{
err = false;
err_info = "Log Negative Number...";
break;
}
else
return log10(a);
case 4: if (a<0)
{
err = false;
err_info = "Ln Negative Number...";
break;
}
else
return log(a);
case 5: return exp(a);
case 6: if (a<0)
{
err = false;
err_info = "Sqrt Negative Number...";
break;
}
else
return sqrt(a);
case 7: return fabs(a);
case 8: if (fabs(a)>1)
{
err = false;
err_info = "Operating Number Over Arcsin Domain...";
break;
}
else
return asin(a);
case 9: if (fabs(a)>1)
{
err = false;
err_info = "Operating Number Over Arccos Domain...";
break;
}
else
return acos(a);
case 10:return atan(a);
case 11:return sinh(a);
case 12:return cosh(a);
case 13:return tanh(a);
default:err = false;
err_info = "Invalid Function Input...";
return -1;
}
}
double work(char *suffix)
{
int i = 0;
char c = suffix[0];
double x;
stack<double> S;
stack<string> SS;
double a, b;
while((c!='\0') && (err))
{
double w1 = 10.0;
double w2 = 1.0;
bool flag = false;
if (CheckChar(c)==0)
{
x = 0;
while (CheckChar(c)==0)
{
if (c=='.')
{
w1 = 1.0;
w2 = 10.0;
flag = true;
}
else
{
x = w1*x + (c-'0')/w2;
if (flag) w2 *= 10;
}
c = suffix[++i];
}
S.push(x);
}
else if (c==')')
{
a = S.top();
S.pop();
string function = SS.top();
SS.pop();
S.push(calc(a,function));
}
else if (CheckChar(c)==1)
{
b = S.top();
S.pop();
a = S.top();
S.pop();
S.push(calculate(a,c,b));
}
else if (CheckChar(c)==2)
{
string function;
while(c!='(')
{
if (c<'a') c = c+32;
function = function + c;
c = suffix[++i];
}
SS.push(function);
}
c = suffix[++i];
}
return S.top();
}
string standardize(string s)
{
int i = s.find(' ', 0);
while (i!=string::npos)
{
s.erase(i, 1);
i = s.find(' ', 0);
}
int n = s.find(';', 0);
if (n!=-1)
s.erase(n);
return s;
}
void Checkexpress(string &s)
{
int i, j, n, l = 0;
n = s.length();
for (i=0;i<n;i++)
{
if (s[i]=='(') l++;
if (s[i]==')') l--;
if (l<0)
{
err = false;
err_info = "Bracket Not Match...";
break;
}
if (s[i]=='(')
{
if (s[i+1]!='(' && s[i+1]!='-' && CheckChar(s[i+1])==1)
{
err = false;
err_info="Lack of Operating Number...";
}
}
else if (s[i]==')')
{
int x = CheckChar(s[i+1]);
if (x==0||x==2||s[i+1]=='(')
{
err = false;
err_info = "Lack of Operator...";
}
}
else if (CheckChar(s[i])==-1)
{
err = false;
err_info = "Invalid Operator...";
break;
}
else if (CheckChar(s[i])==1)
{
if (s[i+1]!='(' && CheckChar(s[i+1])==1)
{
err = false;
err_info = "Lack of Operating Number...";
}
}
else if (CheckChar(s[i])==2)
{
if (!(CheckChar(s[i+1])==2))
if (s[i+1]!='(')
{
err = false;
err_info = "Illegal Function Called...";
}
}
}
if (i==n && l!=0)
{
err = false;
err_info = "Bracket Not Match...";
}
}
void gettime(int &y, int &m, int &d)
{
time_t timer;
time(&timer);
tm* t_tm = localtime(&timer);
y = t_tm->tm_year + 1900;
m = t_tm->tm_mon + 1;
d = t_tm->tm_mday;
}
bool iscputime(string s)
{
int n = s.length();
if (n>8) return false;
int i = 0;
while (s[i]!='.'&&CheckChar(s[i])==0) i++;
if (s[i++]!=':') return false;
while (s[i]!='.'&&CheckChar(s[i])==0) i++;
if (s[i++]!=':') return false;
while (s[i]!='.'&&CheckChar(s[i])==0) i++;
if (s[i]!='\0') return false;
return true;
}
void welcome()
{
cout<<"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"<<endl;
cout<<"$ xxxxx x x xxxxx x x x x xxxxxxx xxxxxxx xxxxx $"<<endl;
cout<<"$ x x x x x x x x x x x x x x x $"<<endl;
cout<<"$x xxxxx x x x x x xxxxx x x x xxxxx $"<<endl;
cout<<"$ x x x x x x x x x x x x x x x $"<<endl;
cout<<"$ xxxxxx x xxxxxx xxxxx xxxxxxx xxxxxx x x x xxxxxxx x x$"<<endl;
cout<<"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"<<endl;
cout<<" Made By Welcome.Z [Version Beta 1.00] Issue Date:1/7/12 \n"<<endl;
int y, m, d, r;
bool ava = true;
gettime(y, m, d);
if (!(y==2012&&m<=8)) ava = false;
else r = 31 * (8 - m) + 32 - d;
if (ava)
{
cout<<" This beta version expired on 1st of September. Just "<<r<<" day";
if (r!=1) cout<<'s';
cout<<" remaining. \n"<<endl;
}
else
{
system("color fc");
cout<<"\n This Beta version has expired."<<endl;
cout<<" Please contact the author to obtain the latest version."<<endl;
cout<<" E-mail: ok_delphi@126.com"<<endl;
char p = getch();
if (p!='`') exit(0);
}
//while(!kbhit()){}
}
bool legalname(string s)
{
if (s!="calculator beta 1.0")
{
system("color fc");
cout<<"You have mandatory renamed the program, which is prohibited by author."<<endl;
cout<<"Change the official name back or you will never normal startup the process."<<endl;
char q = getch();
if (q=='`')
{
system("cls");
return true;
}
else return false;
}
return true;
}
bool rebuilt()
{
string s, u;
system("tasklist /fi \"imagename eq notepad.exe\" /v >tas.txt");
ifstream ii("tas.txt");
while (!ii.eof())
{
ii>>s;
if (iscputime(s))
{
getline(ii, s);
int t = s.length();
while (s[--t]!='.') s.erase(t, 1);
s.erase(t, 1);
for (int i=0;i<s.length();i++) s[i]=tolower(s[i]);
if (s==" calculator_in")
{
return false;
ii.clear();
ii.close();
}
}
}
ii.clear();
ii.close();
return true;
}
int main(int argc, char **argv)
{
bool ava;
string s;
s = copyrightname(argv[0]);
if (!legalname(s)) exit(0);
welcome();
cout<<" Press Any Key To Continue . . .\n";
char pp = getch();
string mid;
char suffix[1000];
double answer;
bool exist;
exist = true;
char p;
fstream icin("Calculator_in.txt", ios::in);
ofstream ocout("Calculator_out.txt");
if (icin==0)
{
exist = false;
system("color 0c");
cout<<" Input File Inexistence . . ."<<endl;
cout<<" Please Check The File's Name Or Rebuild It."<<endl;
cout<<" Wanna Rebuild It ? (Y/N) "<<endl;
cout<<" ";
p = getch();
if (!(p=='n'||p=='N'))
{
icin.open("Calculator_in.txt", ios::out);
icin.clear();
icin.close();
system("start Calculator_in.txt");
cout<<"\n Waiting For Rebuild File";
while (!rebuilt())
{
cout<<" ."; Sleep(500);
cout<<" ."; Sleep(500);
cout<<" ."; Sleep(500);
cout<<"\b\b\b\b\b\b \b\b\b\b\b\b"; Sleep(500);
}
system("del /q tas.txt");
cout<<" . . .\n Input File Has Already Rebuilt!"<<endl;
cout<<" Press Any Key To Continue . . .";
char pp = getch();
system("cls");
welcome();
exist = true;
icin.open("Calculator_in.txt", ios::in);
}
else
{
system("cls");
welcome();
cout<<" Mission Failed!"<<endl;
}
}
if (exist)
{
int num = 0;
int sss = 0;
while(!icin.eof())
{
memset(suffix, '\0', sizeof(suffix));
getline(icin, mid);
if (mid=="") continue;
if (mid[0]==';') break;
num++;
mid = standardize(mid);
int i = mid.length() - 1;
if (mid[i]==';') mid.erase(i,1);
ocout<<"Mission "<<num<<":"<<endl;
ocout<<"The middle expression is: "<<mid<<endl;
err = true;
Checkexpress(mid);
if (err)
{
int i = 0;
int j = mid.find('(',i);
while (j!=-1)
{
if (mid[++j]=='-')
mid.insert(j,"0");
j = mid.find('(',j);
}
}
if (err) transform(mid, suffix);
if (err) answer = work(suffix);
if (err)
{
ocout<<"The answer is: "<<answer<<endl<<endl;
sss++;
}
else
{
ocout<<"Calculate failed! ";
ocout<<err_info<<endl<<endl;
}
} if (num==0) ocout<<"No Mission!"<<endl;
else
ocout<<num<<" expressions in sum. "<<sss<<" Successful. "<<num-sss<<" Failed. "<<endl;
ocout<<"_____________________________________________________________";
ocout<<"\nCalculator Beta 1.0 Made By Welcome.Z [Version Beta 1.00] \n";
}
icin.close();
ocout.close();
if (exist)
{
system("color 0a");
cout<<" Mission Complete!!!"<<endl;
cout<<" Whether Show Up The Result ? (Y/N) "<<endl;
cout<<" ";
p = getch();
if (p=='y'||p=='Y'||p=='\0')
{
system("start Calculator_out.txt");
}
}
cout<<"\n Press Any Key To Quit . . . "<<endl;
p = getch();
return 0;
}