学了一个学期的c++,终于到了实战环节了,下面就是我的c++实训——复数计算器。
该计算器要实现的功能
1、能够进行复数的加减乘、自加、减以及比较复数模的大小。
2、有一个测试函数,计算器会随机出复数的加减乘的运算题给用户做,答对可以等分,做完所有题目,计算器会计算出用户最终的得分,还有平均得分。
3、用户的操作会记录在一个文件中,下次使用计算器会有相应的记录,用户可
以得到上次使用的记录。
该计算器所需要的知识点
1、运算符的重载(重载的目的是让运算符可以对复数进行操作,重点是<<和>>的重载).
2、文件的读写。
3、类和结构体。
写程序的思路
1、首先先定义好一个复数类。因为输入输出,加减乘的运算都是基于复数,因此可以把运算符重载的函数定义在类中。
2、定义一个结构体,存放用户的基本信息。
3、然后再根据我们所需要的功能,先把主函数写完。主函数可以大概分为三个部分,读文件、用户使用、写文件。写完主函数基本的程序框架就有了。
3、把运算符重载的函数补全。
4、把复数加减乘等函数补全完。
#include
#include
#include
#include
#include
#include
#define EPS 1e-5
using namespace std;
class CComplex
{
private:
double Real,Image;
public:
CComplex(double real=0,double image=0)
{
Real=real;Image=image;
}
friend istream &operator >>(istream &is,CComplex &com);
friend ostream &operator <<(ostream &os,CComplex &com);
CComplex operator +(CComplex &com);
CComplex operator -(CComplex &com);
CComplex operator *(CComplex &com);
CComplex operator +=(CComplex &com);
CComplex operator -=(CComplex &com);
CComplex operator *=(CComplex &com);
CComplex operator ++();
CComplex operator --();
double mod();
int operator >(CComplex &com);//复数比较大小是没有意义的,所以我们比较模的大小
int operator <(CComplex &com);
int operator !=(CComplex &com);
int operator ==(CComplex &com);
};
struct User//定义一个用户的结构体,存放用户的各项信息
{
char name[20];//用户名
int time;//用户使用次数
double dlave;
int test;//测试次数
int add;//加法次数
int sub;//减法次数
int mul;//乘法次数
double socre[3];
}user;
CComplex CComplex::operator ++()
{
Real++;
Image++;
return *this;
}
CComplex CComplex::operator --()
{
Real--;
Image--;
return *this;
}
CComplex CComplex::operator +=(CComplex &com)
{
Real=Real+com.Real;
Image=Image-com.Image;
return *this;
}
CComplex CComplex::operator -=(CComplex &com)
{
Real=Real-com.Real;
Image=Image-com.Image;
return *this;
}
CComplex CComplex::operator *=(CComplex &com)
{
double nReal=Real*com.Real-Image*com.Image;
double nImage=Image*com.Real+Image*com.Image;
Real=nReal;
Image=nImage;
return *this;
}
int CComplex::operator ==(CComplex &com)
{
if(Real==com.Real&&Image==com.Image)
return 1;
else
return 0;
}
int CComplex::operator !=(CComplex &com)
{
if(*this!=com)
return 1;
else
return 0;
}
double CComplex::mod()//用来比较复数模的大小
{
return Real*Real+Image*Image;
}
int CComplex::operator >(CComplex &com)
{
if(mod()>com.mod())
return 1;
else
return 0;
}
int CComplex::operator <(CComplex &com)
{
if(mod()<com.mod())
return true;
else
return false;
}
istream &operator >>(istream &is,CComplex &com)//重载输入流函数,使用户规范性输入数字
{
char s[80];//我们要输入i和运算符所以会考虑用字符串存放
is>>s;
int len=strlen(s);
int n=0,sign=1;//sign的作用是用来判断所输入的是正数还是负数
com.Image=com.Real=0;
for(int k=0;k<len;k++)
{
if((s[k]<'0'||s[k]>'9')&&(s[k]!='+'&&s[k]!='-'&&s[k]!='i'))
{
cout<<"输入错误!"<<endl;
return is;
}
}
for(int k=0;k<len;)
{
if(n!=0&&s[k]=='-'||s[k]=='+')
{
com.Real=sign*n;
n=0;
}
if(s[k]=='-')
{
sign=-1;k++;
}
if(s[k]=='+')
{
sign=1;k++;
}
if(s[k]=='i')
{
if(k!=len-1)
cout<<"输入错误!\n";
else
{
if(n==0)
n=1;
com.Image=sign*n;
}
break;
}
while(s[k]>='0'&&s[k]<='9')
{
n=n*10+s[k]-'0';
k++;
}
}
if(s[len-1]!='i'&&n!=0)
com.Real=n*sign;
return is;
}
ostream &operator<<(ostream &os,CComplex &com)//重载输出运算符,使程序可以直接输出一个复数类
{
if(fabs(com.Image)<EPS)
os<<com.Real;
else if(fabs(com.Real)<EPS)
os<<com.Image<<"i";
else if(com.Image>0)
os<<com.Real<<"+"<<com.Image<<"i";
else
os<<com.Real<<com.Image<<"i";
return os;
}
CComplex CComplex::operator +(CComplex &com)
{
CComplex sum;
sum.Real=this->Real+com.Real;
sum.Image=this->Image+com.Image;
return sum;
}
CComplex CComplex::operator -(CComplex &com)
{
CComplex sub;
sub.Real=Real-com.Real;
sub.Image=Image-com.Image;
return sub;
}
CComplex CComplex::operator *(CComplex &com)
{
CComplex mul;
mul.Real=Real*com.Real-Image*com.Image;
mul.Image=Image*com.Real+Real*com.Image;
return mul;
}
void test()
{
user.test++;
system("cls");
cout<<"共10道题,每道题10分,满分100分\n";
double real1,real2,image1,image2,real3,real4,image3,image4;
CComplex answer,tmp;
int score=0;
char op;
for(int i=0;i<=9;i++)
{
real1=rand()%200-100;
image1=rand()%200-100;
real2=rand()%200-100;
image2=rand()%200-100;
CComplex a(real1,image1),b(real2,image2);
real3=rand()%20-10;
image3=rand()%20-10;
real4=rand()%20-10;
image4=rand()%20-10;
CComplex c(real3,image3),d(real4,image4);
op=rand()%3;
switch(op)
{
case 0:
answer=a+b;
cout<<"("<<a<<")+( "<<b<<")=";
break;
case 1:
answer=a-b;
cout<<"("<<a<<")-("<<b<<")=";
break;
case 2:
answer=a*b;
cout<<"("<<a<<")*("<<b<<")=";
break;
}
cin>>tmp;
if(answer==tmp)
{
score=score+10;
}
else
{
cout<<"这题做错了!";
cout<<"这题的答案为:"<<answer<<endl;
}
}
cout<<"你最后的得分是:"<<score<<endl;
if(user.test<=3)
{
user.dlave=0;
user.socre[user.test-1]=score;
for(int i=0;i<user.test;i++)
user.dlave+=user.socre[i];
user.dlave=user.dlave/user.test;
}
else
{
user.socre[0]=user.socre[1];
user.socre[1]=user.socre[2];
user.socre[2]=score;
user.dlave=0;
for(int i=0;i<3;i++)
user.dlave+=user.socre[i];
user.dlave=user.dlave/3;
}
cout<<"请按任意键继续\n";
cout.flush();
cin.get();
cin.get();
}
void add()
{
user.add++;
CComplex num1,num2,sum,zero(0,0);
cout<<"加法计算\n"<<"请输入至少两个复数,并且以0结束"<<endl;
cout<<"请输入第1个复数:";
cin>>num1;
cout<<"请输入第2个复数:";
cin>>num2;
sum=num1+num2;
cout<<"请输入第3个复数:";
cin>>num1;
int i=4;
while(!(num1==zero))
{
sum=sum+num1;
cout<<"请输入第"<<i<<"个复数:";
cin>>num1;
i++;
}
cout<<"加法计算的结果:"<<sum<<endl;
cout<<"按任意键继续"<<endl;
cout.flush();
cin.get();
cin.get();
}
void sub()
{
user.sub++;
CComplex num1,num2,sub,zero(0,0);
cout<<"减法计算\n请至少输入两个复数,并且以零结束\n";
cout<<"请输入第1个复数:";
cin>>num1;
cout<<"请输入第2个复数:";
cin>>num2;
sub=num1-num2;
cout<<"请输入第3个复数:";
cin>>num1;
int i=4;
while(!(num1==zero))
{
sub=sub-num1;
cout<<"请输入入第"<<i<<"个复数:";
cin>>num1;
i++;
}
cout<<"减法运算的结果是:"<<sub<<endl;
cout<<"请按任意键继续\n";
cin.get();
cin.get();
}
void mul()
{
user.mul++;
CComplex num1,num2,mul,zero(0,0);
cout<<"乘法计算\n请输入至少两个复数,并且以零结束"<<endl;
cout<<"请输入第1个复数:";
cin>>num1;
cout<<"请输入第2的复数:";
cin>>num2;
mul=num1*num2;
cout<<"请输入第3个复数:";
cin>>num1;
int i=4;
while(!(num1==zero))
{
mul=mul*num1;
cout<<"请输入第"<<i<<"个复数:";
cin>>num1;
i++;
}
cout<<"乘法计算的结果是:"<<mul<<endl;
cout<<"请按任意键继续"<<endl;
cin.get();
cin.get();
}
void add1()
{
user.add++;
CComplex num1;
cout<<"请输入一个复数:";
cin>>num1;
num1=num1+num1;
cout<<"自加的结果为:"<<num1<<endl;
cout<<"请按任意键继续"<<endl;
cout.flush();//强制写文件,避免数据被缓存可能引起的数据丢失
cin.get();
cin.get();
}
void sub1()
{
user.sub++;
CComplex num1;
cout<<"请输入一个复数:";
cin>>num1;
num1=num1-num1;
cout<<"自减结果为:"<<num1<<endl;
cout<<"请按任意键继续"<<endl;
cout.flush();
cin.get();
cin.get();
}
void compare()
{
CComplex num1,num2;
cout<<"输入两个复数"<<endl;
cout<<"请输入第一个复数:";
cin>>num1;
cout<<"请输入第二个复数:";
cin>>num2;
if(num1==num2)
cout<<"\n这两个复数相等"<<endl;
else if(num1>num2)
cout<<num1<<"的模大于"<<num2<<"的模"<<endl;
else if(num1<num2)
cout<<num1<<"的模小于"<<num2<<"的模"<<endl;
else
cout<<"这两个复数的模相等"<<endl;
cout<<"请按任意键继续"<<endl;
cin.get();
cin.get();
}
void userprint()
{
cout<<"用户姓名:"<<user.name<<"\t使用次数为:"<<user.time<<endl;
cout<<"加法次数:"<<user.add<<"\t减法次数;"<<user.sub<<endl;
cout<<"乘法次数:"<<user.mul<<"\t测试次数:"<<user.test<<endl;
cout<<"平均成绩:"<<user.dlave<<endl;
}
void login()//读文件
{
char name[20];
cout<<"请输入您的姓名:";
cin.getline(name,20);
User user1;
ifstream infile;
infile.open("user.dat",ios::binary|ios::in);
int ch;
infile.seekg(0,ios::beg);
ch=infile.tellg();
if(ch==-1)//新文件
{
cout<<"没有原始记录文件,您是第一位用户!\n";
strcpy(user.name,name);
user.time++;
infile.close();
cin.get();
ofstream file("user.dat",ios::binary);
return;
}
infile.read((char*)&user1,sizeof(User));
while(!infile.eof())//旧文件
{
if(strcmp(user1.name,name)==0)//旧文件旧用户
{
user=user1;
user.time++;
cout<<"欢迎您再次使用Sveinn的复数计算器"<<endl;
userprint();
cin.get();
infile.close();
return;
}
infile.read((char*)&user1,sizeof(User));
}
cout<<"欢迎您使用Sveinn的复数计算器!"<<endl;//旧文件新用户
cin.get();
strcpy(user.name,name);
user.time++;
infile.close();
return;
}
void savefile()
{
userprint();
fstream file;
User user1;
file.open("user.dat",ios::binary|ios::out|ios::in);
if(!file)
{
cout<<"文件打开失败!"<<endl;
return;
}
file.seekp(0,ios::beg);//把文件定义到文件头
while(!file.eof())
{
file.read((char*)&user1,sizeof(User));//旧用户
if(strcmp(user1.name,user.name)==0)
{
file.seekp(-80,ios::cur);
file.write((char*)&user,sizeof(User));
file.close();
return;
}
}
file.close();
fstream outfile;//新用户
outfile.open("user.dat",ios::binary|ios::out|ios::in);
cout<<user.name;
outfile.seekp(0,ios::end);
outfile.write((char*)&user,sizeof(User));
outfile.close();
return;
}
int main()
{
srand(time(NULL));
login();//调用文件写入函数
char choice[20];
do
{
system("cls");
cout<<"========================================="<<endl;
cout<<"======欢迎使用Sveinn的复数计算器========="<<endl;
cout<<"======实现以下功能请按对应键(1-7)======"<<endl;
cout<<"=========================================\n\n"<<endl;
cout<<"==================菜单==================="<<endl;
cout<<"1、加法计算\t2、减法计算\n";
cout<<"3、乘法计算\t4、测试\n";
cout<<"5、自加计算\t6、自减计算\n";
cout<<"7、比较复数大小\t0、退出"<<endl;
cout<<"========================================="<<endl;
cin>>choice;
if(strcmp(choice,"1")==0)
add();
else if(strcmp(choice,"2")==0)
sub();
else if(strcmp(choice,"3")==0)
mul();
else if(strcmp(choice,"4")==0)
test();
else if(strcmp(choice,"5")==0)
add1();
else if(strcmp(choice,"6")==0)
sub1();
else if(strcmp(choice,"7")==0)
compare();
else if(strcmp(choice,"0")==0)
{
cout<<"\n\n欢迎下次继续使用Sveinn计算器!\n\n";
break;
}
else
{
cout<<"\n输入错误,请按任意键后重新输入!\n";
cin.get();
cin.get();
}
}while(strcmp(choice,"0"));
savefile();
return 0;
}