1 #include<iostream>
2 #include<cmath>
3 #include<cstdlib>
4 #include<cstring>
5 #include<fstream>
6 #include<ctime>
7
8 #define EPS 1e-5 //定义精度常数
9
10 using namespace std; //使用标准空间命名std
11 namespace NameCCom //定义命名空间NameCCom
12 {
13 class CCom //定义一个CCom类
14 {
15 public:
16 double Real,Image;
17 CCom(double real=0,double image=0) //构造函数
18 {
19 Real=real;
20 Image=image;
21 }
22 friend istream & operator>>(istream &is,CCom &com); //重载输入
23 friend ostream & operator<<(ostream &os,CCom &com); //重载输出
24 CCom operator+(CCom &com); //加法重载
25 CCom operator-(CCom &com); //减法重载
26 CCom operator*(CCom &com); //乘法重载
27 CCom operator/(CCom &com); //除法重载
28 CCom operator+=(CCom &com); //加法赋值重载
29 CCom operator-=(CCom &com); //减法赋值重载
30 CCom operator*=(CCom &com); //乘法赋值重载
31 CCom operator/=(CCom &com); //除法赋值重载
32 double mod(void); //求复数的模
33 int operator>(CCom &com);
34 int operator<(CCom &com);
35 int operator!=(CCom &com);
36 int operator==(CCom &com);
37 };
38
39 struct User //定义用户结构体类型
40 {
41 char szName[20]; //用户名
42 int nTime; //使用次数
43 int nTest; //测试次数
44 double alAve; //平均成绩
45 int nAdd; //加法次数
46 int nSub; //减法次数
47 int nMul; //乘法次数
48 int nDiv; //除法次数
49 double dlScore[3]; //3次测试得分
50 }user; //定义全局变量
51
52 double CCom::mod() //求复数的模,返回实部平方与虚部平方和的开方
53 {
54 return sqrt(Real*Real+Image*Image);
55 }
56 int CCom::operator>(CCom &com) //重载运算符">",比较模的大小
57 {
58 if(mod()>com.mod())
59 return 1; //若大,则返回1
60 else
61 return 0; //否则,则返回0
62 }
63 int CCom::operator<(CCom &com) //重载运算符"<",比较模的大小
64 {
65 if(mod()<com.mod())
66 return 1; //若小,则返回1
67 else
68 return 0; //否则,则返回0
69 }
70 int CCom::operator!=(CCom &com) //重载运算符"!=",分别判断复数的实部和虚部
71 {
72 if(*this==com)
73 return 0; //若相等,则返回0
74 else
75 return 1; //否则,则返回1
76 }
77
78 istream & operator>>(istream &is,CCom &com) //重载输入,可以输入a+bi的形式
79 {
80 cout<<"请输入复数:";
81 char s[80];
82 is>>s; //用字符串的形式接受复数
83 int len=strlen(s); //求出字符串的长度
84 int n=0,sign=1; //n为当前从字符串中提取出来的数字,初始化为0;sign是标记符号,初始化为正
85 com.Image=com.Real=0;
86 for(int k=0;k<len;k++) //判断接受的字符串是否合法
87 {
88 if((s[k]<'0' || s[k]> '9') && (s[k]!='+' && s[k]!='-' && s[k]!='i'))
89 {
90 cout<<"error"<<endl;
91 return is; //错误,输出出错信息并返回
92 }
93 }
94 for(int k=0;k<len;) //顺序识别字符串中各字符
95 {
96 if(n!=0 &&(s[k]=='-'||s[k]=='+')) //当前字符是否是符号位
97 {
98 com.Real=sign*n; //sign是符号位,且n!=0,即n已被赋值,表明当前读取的是虚部的符号
99 n=0; //将原n*sign值赋给实部,将n清零,准备接受虚部的值
100 }
101 if(s[k]=='-') //当前字符为负号
102 {
103 sign=-1;k++; //给符号标志赋值
104 }
105 if(s[k]=='+') //当前字符为正号
106 {
107 sign=1;k++; //给符号标志赋值
108 }
109 if(s[k]=='i') //当前字符为'i'
110 {
111 if(k!=len-1) //判断字符'i'是否为字符串中作后一个字符
112 cout<<"error\n"; //如果不是,说明复数数据格式错误
113 else
114 com.Image=sign*n; //如果是最后一个字符,复数对象已接受完,用sign*n为虚部赋值
115 break;
116 }
117 while(s[k]>='0' && s[k]<='9') //如果当前字符在0~9之间,将数字字符转换成数字数值
118 {
119 n=n*10+s[k]-'0';
120 k++;
121 }
122 }
123 if(s[len-1]!='i' && n!=0) //如果最后一个字符不是'i',表示复数对象内只有实部,没有虚部
124 {
125 com.Real=n*sign;
126 }
127 return is;
128 }
129
130 ostream & operator<<(ostream &os,CCom &com) //重载输入
131 {
132 if(fabs(com.Image)<EPS) // 如果虚部为0
133 os<<com.Real; //只输出实部
134 else if((fabs(com.Real)<EPS)) //如果实部为0
135 os<<com.Image<<"i"; //只输出虚部
136 else if(com.Image>0)
137 os<<com.Real<<"+"<<com.Image<<"i";
138 else
139 os<<com.Real<<com.Image<<"i"; //虚部为正
140 return os;
141 }
142
143 CCom CCom::operator+(CCom &com) //加法重载
144 {
145 CCom sum;
146 sum.Real=Real+com.Real; //实部相加
147 sum.Image=Image+com.Image; //虚部相加
148 return sum;
149 }
150 CCom CCom::operator-(CCom &com) //减法重载
151 {
152 CCom sub;
153 sub.Real=Real-com.Real; //实部相减
154 sub.Image=Image-com.Image; //虚部相减
155 return sub;
156 }
157 CCom CCom::operator*(CCom &com) //乘法重载
158 {
159 CCom multi;
160 multi.Real=Real*com.Real-Image*com.Image; //实部乘积
161 multi.Image=Real*com.Image+Image*com.Real; //虚部乘积
162 return multi;
163 }
164 CCom CCom::operator/(CCom &com) //除法重载
165 {
166 CCom div;
167 div.Real=(Real*com.Real+Image*com.Image)/(com.Real*com.Real+com.Image*com.Image); //实部除积
168 div.Image=(Image*com.Real-Real*com.Image)/(com.Real*com.Real+com.Image*com.Image); //虚部除积
169 return div;
170 }
171 CCom CCom::operator+=(CCom &com) //重载加法赋值
172 {
173 Real=Real+com.Real; //实部相加
174 Image=Image+com.Image; //虚部相加
175 return *this;
176 }
177 CCom CCom::operator-=(CCom &com) //重载减法赋值
178 {
179 Real=Real-com.Real; //实部相减
180 Image=Image-com.Image; //虚部相减
181 return *this;
182 }
183 CCom CCom::operator*=(CCom &com) //重载乘法赋值
184 {
185 double nReal=Real*com.Real-Image*com.Image; //实部乘积
186 double nImage=Real*com.Image+Image*com.Real; //虚部乘积
187 Real=nReal;
188 Image=nImage;
189 return *this;
190 }
191 CCom CCom::operator/=(CCom &com) //重载除法赋值
192 {
193 double nReal=(Real*com.Real+Image*com.Image)/(com.Real*com.Real+com.Image*com.Image); //实部除积
194 double nImage=(Image*com.Real-Real*com.Image)/(com.Real*com.Real+com.Image*com.Image); //虚部除积
195 Real=nReal;
196 Image=nImage;
197 return *this;
198 }
199 int CCom::operator==(CCom &com) //重载等于
200 {
201 if(Real==com.Real && Image==com.Image)
202 return 1;
203 else
204 return 0;
205 }
206
207 void Test(void) //测试函数
208 {
209 user.nTest++;
210 cout<<"共10道题,做100以内的加减运算,满分100分:\n";
211 double real1,real2,image1,image2,real3,real4,image3,image4;
212 CCom answer,temp;
213 int score=0;
214 char op;
215 for(int i=0;i<=9;i++) //给复数产生随机值
216 {
217 real1=rand()%200-100;
218 image1=rand()%200-100;
219 real2=rand()%200-100;
220 image2=rand()%200-100;
221 CCom a(real1,image1),b(real2,image2);
222 real3=rand()%20-10;
223 image3=rand()%20-10;
224 real4=rand()%20-10;
225 image4=rand()%20-10;
226 CCom c(real3,image3),d(real4,image4);
227 op=rand()%3; //产生随机加减乘法运算的三个值
228 switch(op)
229 {
230 case 0: //若为0则是加法
231 answer=a+b;
232 cout<<a<<"加上"<<b<<"等于";
233 break;
234 case 1: //若为1则是减法
235 answer=a-b;
236 cout<<a<<"减去"<<b<<"等于";
237 break;
238 case 2: //若为2则是乘法
239 answer=c*d;
240 cout<<c<<"乘以"<<d<<"等于";
241 break;
242 }
243 cin>>temp; //输入用户计算值
244 if(answer==temp) //比较用户计算值
245 {
246 score+=10; //若正确则加10分
247 }
248 else
249 {
250 cout<<"此题做错了\n";
251 cout<<"正确答案为:"<<answer<<endl;
252 }
253 }
254 cout<<"你的最后得分是:"<<score<<endl;
255 if(user.nTest<=3)
256 {
257 user.alAve=0;
258 user.dlScore[user.nTest-1]=score;
259 for(int i=0;i<user.nTest;i++)
260 user.alAve+=user.dlScore[i];
261 user.alAve=user.alAve/user.nTest;
262 }
263 else
264 {
265 user.dlScore[0]=user.dlScore[1];
266 user.dlScore[1]=user.dlScore[2];
267 user.dlScore[2]=score;
268 for(int i=0;i<3;i++)
269 user.alAve+=user.dlScore[i];
270 user.alAve=user.alAve/3;
271 }
272 cout<<"请按任意键继续\n";
273 cout.flush();
274 cin.get();
275 cin.get();
276 }
277
278 void Add() //复数加法运算函数
279 {
280 user.nAdd++;
281 CCom num1,num2,sum,Zero(0,0);
282 cout<<"加法计算\n"<<"最少输入两个复数,并且以0结束\n";
283 cout<<"第一个复数:";
284 cin>>num1;
285 cout<<"第二个复数:";
286 cin>>num2;
287 sum=num1+num2;
288 cout<<"第三个复数:";
289 cin>>num1;
290 int i=4;
291 while(!(num1==Zero))
292 {
293 sum=sum+num1;
294 cout<<"第"<<i<<"个复数:";
295 cin>>num1;
296 i++;
297 }
298 cout<<"加法结果是:"<<sum<<endl;
299 cout<<"请按任意键继续\n";
300 cout.flush();
301 cin.get();
302 cin.get();
303 }
304
305 void Sub() //复数减法运算函数
306 {
307 user.nSub++;
308 CCom num1,num2,sub,Zero(0,0);
309 cout<<"最少输入两个复数,并且以0结束\n";
310 cout<<"第1个复数:";
311 cin>>num1;
312 cout<<"第2个复数:";
313 cin>>num2;
314 sub=num1-num2;
315 cout<<"第3个复数:";
316 cin>>num1;
317 int i=4;
318 while(!(num1==Zero))
319 {
320 sub=sub-num1;
321 cout<<"第"<<i<<"个复数:";
322 cin>>num1;
323 i++;
324 }
325 cout<<"减法结果是:"<<sub<<endl;
326 cout<<"请按任意键继续\n";
327 cout.flush();
328 cin.get();
329 cin.get();
330 }
331
332 void Mul() //复数乘法运算函数
333 {
334 user.nMul++;
335 CCom num1,num2,mul,Zero(0,0);
336 cout<<"乘法计算\n"<<"最少输入两个复数,并且以0结束\n";
337 cout<<"第一个复数:";
338 cin>>num1;
339 cout<<"第二个复数:";
340 cin>>num2;
341 mul=num1*num2;
342 cout<<"第三个复数:";
343 cin>>num1;
344 int i=4;
345 while(!(num1==Zero))
346 {
347 mul*=num1;
348 cout<<"第"<<i<<"个复数:";
349 cin>>num1;
350 i++;
351 }
352 cout<<"乘法结果是:"<<mul<<endl;
353 cout<<"请按任意键继续\n";
354 cout.flush();
355 cin.get();
356 cin.get();
357 }
358
359 void Div() //复数除法运算函数
360 {
361 user.nDiv++;
362 CCom num1,num2,div,Zero(0,0);
363 cout<<"除法计算\n"<<"最少输入两个复数,并且以0结束\n";
364 cout<<"第一个复数:";
365 cin>>num1;
366 cout<<"第二个复数:";
367 cin>>num2;
368 div=num1/num2;
369 cout<<"第三个复数:";
370 cin>>num1;
371 int i=4;
372 while(!(num1==Zero))
373 {
374 div/=num1;
375 cout<<"第"<<i<<"个复数:";
376 cin>>num1;
377 i++;
378 }
379 cout<<"除法结果是:"<<div<<endl;
380 cout<<"请按任意键继续\n";
381 cout.flush();
382 cin.get();
383 cin.get();
384 }
385
386 void Mod() //复数求模函数
387 {
388 CCom num,mod;
389 cout<<"请输入一个复数\n";
390 cin>>num;
391 mod=sqrt(num.Real*num.Real+num.Image*num.Image);
392 cout<<"复数的模是:"<<mod<<endl;
393 cout<<"请按任意键继续\n";
394 cout.flush();
395 cin.get();
396 cin.get();
397 }
398
399 void Compare() //两复数比较函数
400 {
401 CCom num1,num2;
402 cout<<"请输入两个复数\n";
403 cout<<"第一个复数:";
404 cin>>num1;
405 cout<<"第二个复数\n";
406 cin>>num2;
407 if(num1==num2)
408 cout<<"这两个复数相等\n";
409 else if(num1>num2)
410 cout<<num1<<"的模大于"<<num2<<"的模\n";
411 else if(num1<num2)
412 cout<<num2<<"的模大于"<<num1<<"的模\n";
413 else
414 cout<<"这两个复数的模相等\n";
415 cout<<"请按任意键继续\n";
416 cin.get();
417 cin.get();
418 }
419
420 void userprint() //输出用户信息函数
421 {
422 cout<<user.szName<<"使用的次数为:"<<user.nTime<<endl;
423 cout<<"其中:\t加法的次数:"<<user.nAdd<<endl;
424 cout<<"\t减法的次数:"<<user.nSub<<endl;
425 cout<<"\t乘法的次数:"<<user.nMul<<endl;
426 cout<<"\t测试次数:"<<user.nTest<<"\t平均成绩:"<<user.alAve<<endl;
427 }
428
429 void Login() //当前用户信息函数
430 {
431 char szName[20];
432 cout<<"请输入您的姓名:";
433 cin.getline(szName,20);
434 ifstream infile;
435 User user1;
436 infile.open("user.dat",ios::binary|ios::in);
437 if(!infile)
438 {
439 cout<<"没有原始记录文件,您是第一个用户!\n";
440 strcpy(user.szName,szName);
441 user.nTest++;
442 return;
443 }
444 infile.read((char *)&user1,sizeof(User));
445 while(!infile.eof())
446 {
447 if(strcmp(user1.szName,szName)==0)
448 {
449 user=user1;
450 user.nTime++;
451 cout<<"欢迎您再次使用复数计算器!";
452 userprint();
453 cin.get();
454 infile.close();
455 return;
456 }
457 infile.read((char *) &user1,sizeof(User));
458 }
459 cout<<"欢迎您再次使用复数计算器!";
460 strcpy(user.szName,szName);
461 user.nTime++;
462 infile.close();
463 return;
464 }
465
466 void SaveFile() //用户资料保存函数
467 {
468 userprint();
469 fstream file;
470 User user1;
471 file.open("user.dat",ios::binary|ios::in|ios::out);
472 if(!file)
473 {
474 cout<<"文件打开错误,不能进行更新!\n";
475 return;
476 }
477 file.seekp(0,ios::beg);
478 while(!file.eof())
479 {
480 file.read((char *)&user1,sizeof(User));
481 if(strcmp(user1.szName,user.szName)==0)
482 {
483 file.seekp(-(sizeof(User)),ios::cur);
484 file.write((char *)&user,sizeof(User));
485 file.close();
486 return;
487 }
488 }
489 file.close();
490 fstream outfile;
491 outfile.open("user.dat",ios::binary|ios::app);
492 outfile.write((char *)&user,sizeof(User));
493 outfile.close();
494 return;
495 }
496 }
497 using namespace NameCCom;
498
499 int main(void) //主函数开始
500 {
501 srand(time(NULL)); //初始化随机数"种子"语句
502 Login(); //当前用户信息函数
503 char strChoise[20]; //定义字符串名
504 do
505 {
506 system("cls");
507 cout<<"\t这是一个复数计算器,可以实现以下功能,请按对应的按键(0-7)\n\n\n";
508 cout<<"\t**************************菜单**************************\n";
509 cout<<"\t1:多复数加法,以0结束\n";
510 cout<<"\t2:多复数减法,以0结束\n";
511 cout<<"\t3:多复数乘法,以0结束\n";
512 cout<<"\t4:多复数除法,以0结束\n";
513 cout<<"\t5:求复数的模\n:";
514 cout<<"\t6:复数比较\n:";
515 cout<<"\t7:测试100以内的复数加减乘法运算,1次测试10道题\n:";
516 cout<<"\t0:退出程序\n\n:";
517 cout<<"\t请您选择:";
518 cin>>strChoise;
519 if(strcmp(strChoise,"1")==0) //用户选1则调用Add()函数
520 Add();
521 else if(strcmp(strChoise,"2")==0) //用户选2则调用Sub()函数
522 Sub();
523 else if(strcmp(strChoise,"3")==0) //用户选3则调用Mul()函数
524 Mul();
525 else if(strcmp(strChoise,"4")==0) //用户选4则调用Div()函数
526 Div();
527 else if(strcmp(strChoise,"5")==0) //用户选5则调用Mod()函数
528 Mod();
529 else if(strcmp(strChoise,"6")==0) //用户选6则调用Compare()函数
530 Compare();
531 else if(strcmp(strChoise,"7")==0) //用户选7则调用Test()函数
532 Test();
533 else if(strcmp(strChoise,"0")==0) //用户选0则结束调用函数
534 {
535 cout<<"\n\n\t欢迎下次继续使用复数计算器!\n\n";
536 break;
537 }
538 else
539 {
540 cout<<"\n\t输入错误,请按任意键继续!\n";
541 cin.get();
542 cin.get();
543 }
544 }
545 while((strcmp(strChoise,"0")));
546 SaveFile(); //调用用户资料保存函数
547 return 0;
548 }