1. 程式人生 > >c++學習筆記之複數計算器

c++學習筆記之複數計算器

準備了一個月的考試終於結束了。總結一下這一個月學到的理論知識,規劃一下1月的計劃。昨天敲了一天的程式碼。複數計算器是我敲的第一個比較大的程式,涉及到的主要知識點是運算子的過載和檔案操作。純程式碼後面再做詳細的介紹。

#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<fstream>
#include<ctime>
#define EPS 1e-5
using namespace std;
namespace NameCComplex //空間域防止混淆 
{
	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(void);
				int operator >(CComplex &com);//型別轉換字元 
				int operator <(CComplex &com);
				int operator !=(CComplex &com);
				int operator ==(CComplex &com);
	};	
	struct User
	{
		char  szname[20];
		int ntime;
		int ntest;
		double dlave;
		int nadd;
		int nsub;
		int nmul;
		double dlsocre[3];
	} user;
	CComplex CComplex::operator ++()
	{
		Real++;
		Image++;
		return *this;
	}
	CComplex CComplex::operator --()
	{
		Real --;
		Image--;
		return *this;
	}
	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 1;
	 	else return 0;
	 }
	 int CComplex::operator !=(CComplex &com)
	 {
	 	if(*this==com)
	 	return 0;
	 	else
	 	return 1;
	 }
	 istream &operator >>(istream&is,CComplex &com)
	 {
	 	cout<<"輸入複數:";
	 	char s[80];
	 	is>>s;
	 	int len=strlen(s);
	 	int n=0,sign=1;
	 	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<<"error"<<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<<"error\n";
				else
				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=Real+com.Real;
	 	sum.Image=Image+com.Image;
	 	return sum;
	 }
	 CComplex CComplex::operator *(CComplex &com)
	 {
	 	CComplex multi;
	 	multi.Real=Real*com.Real-Image*com.Image;
	 	multi.Image=Real*com.Image+Image*com.Real;
	 	return multi;
	 }
	 CComplex CComplex::operator -(CComplex &com)
	 {
	 	CComplex sub;
		sub.Real=Real-com.Real;
		sub.Image=Image-com.Image;
		return sub;	 	
	 }
	 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=Real*com.Image+Image*com.Real;
	 	Real=nReal;
	 	Image=nImage;
	 	return *this;
	 }
	 int CComplex::operator ==(CComplex&com)
	{
		 if(Real==com.Real&&Image==com.Image)
		 return 1;
		 else
		 return 0;
	}
	void test(void)
	{
		user.ntest++;
		cout<<"共10道題,作10以內的加減運算,滿分100分:\n";
		double real1,real2,image1,image2,real3,real4,image3,image4;
		CComplex answer,temp;
		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=c*d;
				cout<<c<<"乘以"<<d<<"等於";
				break;	
			}
			cin>>temp;
			if(answer==temp)
			{
				score+=10;
			}
			else
			{
				cout<<"此題做錯了\n";
				cout<<"正確答案為:"<<answer<<endl;
			}
		}
		cout<<"你的最後得分是:"<<score<<endl;
		if(user.ntest<=3)
		{
			user.dlave=0;
			user.dlsocre[user.ntest-1]=score;
			for(int i=0;i<user.ntest;i++)
			user.dlave+=user.dlsocre[i];
			user.dlave=user.dlave/user.ntest;
		 } 
		 else
		 {
		 	user.dlsocre[0]=user.dlsocre[1];
		 	user.dlsocre[1]=user.dlsocre[2];
		 	user.dlsocre[2]=score;
		 	user.dlave=0;
		 	for(int i=0;i<3;i++)
		 	user.dlave+=user.dlsocre[i];
		 	user.dlave=user.dlave/3;
		 }
		 cout<<"按任意鍵繼續\n";
		 cout.flush();
		 cin.get();
		 cin.get();
	}
	void add()
	{
		user.nadd++;
		CComplex num1,num2,sum,zero(0,0);
		cout<<"加法計算\n"<<"最少輸入兩個複數,並且以零結束\n";
		cout<<"第一個複數";
		cin>>num1;
		cout<<"第二個複數";
		cin>>num2;
		sum=num1+num2;
		cout<<"第三個複數";
		cin>>num1;
		int i=4;
		while(!(num1==zero))
		{
			sum=sum+num1;
			cout<<"第"<<i<<"個複數";
			cin>>num1;
			i++;
		}
		cout<<"加法計算的結果是"<<sum<<endl;
		cout<<"按任意鍵繼續\n";
		cout.flush();
		cin.get();
		cin.get();
	}
	void sub()
	{
		user.nsub++;
		CComplex num1,num2,sub,zero(0,0);
		cout<<"減法計算\n"<<"最少輸入兩個複數,並且以零結束\n";
		cout<<"第一個複數";
		cin>>num1;
		cout<<"第二個複數";
		cin>>num2;
		sub=num1-num2;
		cout<<"第三個複數";
		cin>>num1;
		int i=4;
		while(!(num1==zero))
		{
			sub=sub-num1;
			cout<<"第"<<i<<"個複數";
			cin>>num1;
			i++;
		}
		cout<<"減法運算的結果是"<<sub<<endl;
		cout<<"按任意鍵繼續\n";
		//cout.flush();
		cin.get();
		cin.get();
	}
	void mul()
	{
		user.nmul++;
		CComplex num1,num2,mul,zero(0,0);
		cout<<"乘法計算\n"<<"最少輸入兩個複數,並且以零結束\n";
		cout<<"第一個複數";
		cin>>num1;
		cout<<"第二個複數";
		cin>>num2;
		mul=num1*num2;
		cout<<"第三個複數";
		cin>>num1;
		int i=4;
		while(!(num1==zero))
		{
			num1*=num1;
			cout<<"第"<<i<<"個數";
			cin>>num1;
			i++;
		}
		cout<<"乘法運算的結果是"<<mul<<endl;
		cout<<"按任意鍵繼續\n";
		//cout.flush();
		cin.get();
		cin.get();
	 } 
	 void add1()
	 {
	 	user.nadd++;
		CComplex num1; 
		cin>>num1;
		num1+=num1;
		cout<<"自加結果為"<<num1<<endl;
		cout<<"按任意鍵繼續\n";
		cout.flush();
		cin.get();
		cin.get(); 
	 }
	 void sub1()
	 {
	 	user.nsub++;
		CComplex num1;
		cin>>num1;
		num1-=num1;
		cout<<"自減結果為"<<num1<<endl;
		cout<<"按任意鍵繼續\n";
		cout.flush();
		cin.get();
		cin.get(); 
	 }
	 void compare()
	 {
	 	CComplex num1,num2;
	 	cout<<"輸入兩個複數\n";
	 	cout<<"第一個複數:";
		cin>>num1;
		cout<<"第二個複數";
		cin>>num2;
		if(num1==num2)
		cout<<"這兩個複數相等\n";
		else if(num1>num2)
		cout<<num1<<"的模大於"<<num2<<"的模\n";  
		else if(num1<num2)
		cout<<num2<<"的模大於"<<num1<<"的模\n";  
		else
		cout<<"這兩個複數的模相等\n";
		cout<<"按任意鍵繼續\n";
		cin.get();
		cin.get();
	  } 
	  void userprint()
	  {
	  	cout<<user.szname<<"使用的次數為"<<user.ntime<<endl;
	  	cout<<"其中:\t加法次數:"<<user.nadd<<"\t減去次數:"<<user.nsub<<"/t乘法次數"<<user.nmul<<endl;
	  	cout<<"\t測試次數:"<<user.ntest<<"\t平均成績"<<user.dlave<<endl;
	  }
	  void login()
	  {
	  	char szname[20];
	  	cout<<"請輸入您的姓名:";
	  	cin.getline(szname,20);
	  	ifstream infile;
	  	User user1;
	  	infile.open("user.dat",ios::binary|ios::in);
	  	if(! infile)
	  	{
	  		cout<<"沒有原始記錄檔案,您是第一位使用者!\n";
	  		strcpy(user.szname,szname);
	  		user.ntime++;
	  		return;
		  }
		  infile.read((char*)&user1,sizeof(User));
		  while(!infile.eof())
		  {
		  	if(strcmp(user1.szname,szname)==0)
		  	{
		  		user=user1;
		  		user.ntime++;
		  		cout<<"歡迎您再次使用複數計算器";
		  		userprint();
				cin.get();
				infile.close();
				return; 
			  }
			  infile.read((char *)&user1,sizeof(User));
		  }
		  strcpy(user.szname,szname);
		  user.ntime++;
		  infile.close();
		  return;
	  }
	  void savefile()
	  {
	  	userprint();
	  	fstream file;
	  	User user1;
	  	file.open("user.dat",ios::binary|ios::in|ios::out);
	  	if(!file)
	  	{
	  		cout<<"檔案開啟錯誤,不能將記錄更新\n";
	  		 return ;
		  }
		file.seekp(0,ios::beg);
		while(!file.eof()) 
		{
			file.read((char*)&user1,sizeof(User));
			if(strcmp(user1.szname,user.szname)==0)
			{
			file.seekp(-(sizeof(User)),ios::cur);
			file.write((char*)&user,sizeof(User));
			file.close();
			return;
			}
		}
		file.close();
		fstream outfile;
		outfile.open("user.dat",ios::binary|ios::app);
		outfile.write((char*)&user,sizeof(User));
		outfile.close();
		return;
	  }  
}
using namespace NameCComplex;
int main(void)
{
	srand(time(NULL));
	login();
	char strChoice[20];
	do
	{
		system("cls");
		cout<<"\t這是一個簡單的複數計算器程式,可以實現以下功能,請按對應的鍵(1~7)進入\n\n\n";
		cout<<"\t==============MENU==============\n";
		cin>>strChoice;
		if(strcmp(strChoice,"1")==0)
		add();
		else if(strcmp(strChoice,"2")==0)
		sub();
		else if(strcmp(strChoice,"3")==0)
		test();
		else if(strcmp(strChoice,"4")==0)
		mul();
		else if(strcmp(strChoice,"5")==0)
		add1();
		else if(strcmp(strChoice,"6")==0)
		sub1();
		else if(strcmp(strChoice,"7")==0)
		compare();
		else if(strcmp(strChoice,"0")==0)
		{
			cout<<"\n\n\t歡迎下次繼續使用計算器!\n\n";
			break;
		}
		else
		{
			cout<<"\n\t輸入錯誤,請按任意鍵後重新輸入!\n";
			cin.get();
			cin.get();
		}
	}
	while((strcmp(strChoice,"0")));
	savefile();
	return 0;
}