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 "; //如果不是,说明复数数据格式错误 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分: "; 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<<"此题做错了 "; 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<<"请按任意键继续 "; 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<<"加法计算 "<<"最少输入两个复数,并且以0结束 "; 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<<"请按任意键继续 "; 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结束 "; 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<<"请按任意键继续 "; 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<<"乘法计算 "<<"最少输入两个复数,并且以0结束 "; 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<<"请按任意键继续 "; 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<<"除法计算 "<<"最少输入两个复数,并且以0结束 "; 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<<"请按任意键继续 "; 381 cout.flush(); 382 cin.get(); 383 cin.get(); 384 } 385 386 void Mod() //复数求模函数 387 { 388 CCom num,mod; 389 cout<<"请输入一个复数 "; 390 cin>>num; 391 mod=sqrt(num.Real*num.Real+num.Image*num.Image); 392 cout<<"复数的模是:"<<mod<<endl; 393 cout<<"请按任意键继续 "; 394 cout.flush(); 395 cin.get(); 396 cin.get(); 397 } 398 399 void Compare() //两复数比较函数 400 { 401 CCom num1,num2; 402 cout<<"请输入两个复数 "; 403 cout<<"第一个复数:"; 404 cin>>num1; 405 cout<<"第二个复数 "; 406 cin>>num2; 407 if(num1==num2) 408 cout<<"这两个复数相等 "; 409 else if(num1>num2) 410 cout<<num1<<"的模大于"<<num2<<"的模 "; 411 else if(num1<num2) 412 cout<<num2<<"的模大于"<<num1<<"的模 "; 413 else 414 cout<<"这两个复数的模相等 "; 415 cout<<"请按任意键继续 "; 416 cin.get(); 417 cin.get(); 418 } 419 420 void userprint() //输出用户信息函数 421 { 422 cout<<user.szName<<"使用的次数为:"<<user.nTime<<endl; 423 cout<<"其中: 加法的次数:"<<user.nAdd<<endl; 424 cout<<" 减法的次数:"<<user.nSub<<endl; 425 cout<<" 乘法的次数:"<<user.nMul<<endl; 426 cout<<" 测试次数:"<<user.nTest<<" 平均成绩:"<<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<<"没有原始记录文件,您是第一个用户! "; 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<<"文件打开错误,不能进行更新! "; 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<<" 这是一个复数计算器,可以实现以下功能,请按对应的按键(0-7) "; 508 cout<<" **************************菜单************************** "; 509 cout<<" 1:多复数加法,以0结束 "; 510 cout<<" 2:多复数减法,以0结束 "; 511 cout<<" 3:多复数乘法,以0结束 "; 512 cout<<" 4:多复数除法,以0结束 "; 513 cout<<" 5:求复数的模 :"; 514 cout<<" 6:复数比较 :"; 515 cout<<" 7:测试100以内的复数加减乘法运算,1次测试10道题 :"; 516 cout<<" 0:退出程序 :"; 517 cout<<" 请您选择:"; 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<<" 欢迎下次继续使用复数计算器! "; 536 break; 537 } 538 else 539 { 540 cout<<" 输入错误,请按任意键继续! "; 541 cin.get(); 542 cin.get(); 543 } 544 } 545 while((strcmp(strChoise,"0"))); 546 SaveFile(); //调用用户资料保存函数 547 return 0; 548 }