_Phoebe__ 2022-03-28 23:34 采纳率: 96.9%
浏览 63
已结题

分数计算器实现 bug多想知道怎么改

主要问题还挺大的 :
1.答案中没有约分
2.计算过程 加减乘除 我想输入-1停止但是实现不了 会一直循环下去

/*(1)为有理数定义一个Rational类。有理数可以表示成为两个相除的整数,如3/4、13/3等。将有理数表示成int类型的两个值相除,分别表示分子和分母;
(2)通过接收从键盘输入a/b形式的分数生成有理数类的对象,在程序中可以识别出分子和分母并正确赋值;(要判断分母是否为0);
(3)采用运算符重载方法定义有理数的加、减、乘、除运算;(需要判断除数是否为0)
(4)设计有理数计算器测试程序,采用由计算机随机出题(用随机数),用户答题的形式,对有理数的加法、减法、乘法和除法进行测试。
(5)(选做题)设计记录功能,可以记录下不同用户使用计算器的情况,记录以文件形式保存。程序运行时要求输入用户名,显示该用户以前的记录。用户记录包括:做了多少次加法、减法、乘法和除法,进行测试的次数,测试的平均分等,在退出计算器程序时用新的用户记录代替原有记录。*/
#include <bits/stdc++.h>
using namespace std;
struct User //用户结构体类型定义
{
   char szName[20]; //用户名
   int nTime; //使用次数
   int nTest; //测试次数
   double alAve; //平均成绩
   int nAdd; //加法次数
   int nSub; //减法次数
   int nMul; //乘法次数
   double dlScore[3]; //3次测试得分
}user;
class rational  
{
public:
    void print();                    //输出函数
    rational(int x=0,int y=0);
    virtual ~rational();
    void optimization();            //优化有理数函数
    friend rational operator + (rational num1,rational num2);    //重载运算符+
    friend rational operator - (rational num1,rational num2);    //重载运算符-
    friend rational operator * (rational num1,rational num2);    //重载运算符*
    friend rational operator / (rational num1,rational num2);    //重载运算符/
    friend istream& operator>>(istream& is, rational& r);//重载流输入 
    friend ostream& operator<<(ostream& os, rational& r);//重载流输出 
    friend bool operator ==(rational num1,rational num2);        //重载运算符==
    friend double real(rational x);                            //声明转换函数
private:

    int denominator;                //分母
    int numerator;                    //分子
};
rational::rational(int x,int y)
{
    numerator= x;
    denominator= y;
    optimization();            //有理数优化
}

rational::~rational()
{
}
void rational::print()
{
    cout<<numerator;
    if(numerator!=0 && denominator!=1)
        cout<<"/"<<denominator<<"\n";
    else
        cout<<"\n";
}
void rational::optimization()
{
    int gcd;
    int i=1;
    if(numerator==0)        //如果分子为零,则分母为1后返回
    {
        denominator= 1;
        return;
    }
    //取分子分母中较小的数作为公约数极限
    gcd= (abs(numerator)>abs(denominator))?abs(numerator):abs(denominator);
    if(gcd==0)
        return;                //若为0,则返回
    for(int i=gcd;i>1;i--)        //用循环找最大公约数
        if((numerator%i==0)&& (denominator%i==0))
            break;
    numerator/=i;            //i为最大公约数,将分子分母整除它,重新赋值
    denominator/=i;
    //若分子分母均为负数,则结果为正
    if(numerator<0 && denominator<0)
    {
        numerator= -numerator;
        denominator= -denominator;
    }
    //若分子分母只有一个为负数,则调整为分子取负,分母取正
    else if(numerator<0 || denominator<0)
    {
        numerator= -abs(numerator);
        denominator=abs(denominator);
    }
}
rational operator + (rational num1,rational num2)
{
    rational temp;
    temp.denominator =num1.denominator *num2.denominator ;
    temp.numerator = num1.numerator *num2.denominator +num1.denominator *num2.numerator ;
    temp.optimization ();
    return  temp;
}
rational operator - (rational num1,rational num2)
{
    rational temp;
    temp.denominator =num1.denominator *num2.denominator ;
    temp.numerator = num1.numerator *num2.denominator -num1.denominator *num2.numerator ;
    temp.optimization ();
    return  temp;
}    
rational operator * (rational num1,rational num2)
{
    rational  temp;
    temp.denominator =num1.denominator *num2.denominator ;
    temp.numerator = num1.numerator *num2.numerator ;
    temp.optimization ();
    return temp;
}

rational operator / (rational num1,rational num2)
{
    rational temp;
    temp.denominator =num1.denominator *num2.numerator  ;
    temp.numerator = num1.numerator *num2.denominator ;
    temp.optimization ();
    return temp;
}

bool operator ==(rational num1,rational num2)
{
    if(num1.numerator ==num2.numerator && num1.denominator ==num2.denominator )
        return true;
    else
        return false;
}        
istream& operator>>(istream& is, rational& r) {
    is >> r.numerator >> r.denominator;
    if (r.denominator != 0) {
        return is;
    }
    else {
        cout << "The denominator is 0, which is illegal. Please try again!" << endl;
        exit(0);
    }
}
ostream& operator<<(ostream& os, rational& r) {
    if (r.numerator % r.denominator == 0) {
        os << r.numerator / r.denominator << endl;
        return os;
    }
    else
        os << r.numerator << "\\" << r.denominator;
    return os;
}
double real(rational x)
{
    return(double(x.numerator)/double(x.denominator));
}    
void Test() //测试函数
{
   user.nTest++;
   cout<<"共10道题,做100以内的加减运算,满分100分:\n";
   double real1,real2,image1,image2,real3,real4,image3,image4;
   rational answer,temp;
   int score=0;
   char op;
   for(int i=0;i<=9;i++)
{
    int m1 = rand() % 100 + 1; //生成1-100的随机数
    int n1 = rand() % 100 + 1;
    int m2 = rand() % 100 + 1;
    int n2 = rand() % 100 + 1;
    rational a(m1,n1),b(m2,n2);
    int m3=rand()%20-10;
    int n3=rand()%20-10;
    int m4=rand()%20-10;
    int n4=rand()%20-10;
    rational c(m3,n3),d(m4,n4);
    op=rand()%4; //产生随机加减乘除运算的三个值
    switch(op)
 {
    case 0:
    answer=a+b;
    cout<<a<<"加上"<<b<<"等于";
    break;
    case 1:
    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.alAve=0;
user.dlScore[user.nTest-1]=score;
for(int i=0;i<user.nTest;i++)
user.alAve+=user.dlScore[i];
user.alAve=user.alAve/user.nTest;
}
else
{
user.dlScore[0]=user.dlScore[1];
user.dlScore[1]=user.dlScore[2];
user.dlScore[2]=score;
for(int i=0;i<3;i++){
user.alAve=0;
user.alAve+=user.dlScore[i];
user.alAve=user.alAve/3;
}
cout<<"请按任意键继续\n";
cout.flush();
cin.get();
cin.get();
}
}
void Add() //加法运算函数
{
   user.nAdd++;
   rational num1,num2,sum,Zero(0,0);
   cout<<"加法计算\n"<<"最少输入两个数,并且以-1结束\n";
   cout<<"第一个数:";
   cin>>num1;
   cout<<"第二个数:";
   cin>>num2;
   sum=num1+num2;
   cout<<"第三个数:";
   cin>>num1;
   int i=4;
   while(1)
{
   sum=sum+num1;
   cout<<"第"<<i<<"个数:";
   cin>>num1;
   i++;
   if(num1==-1)
   break;
}
cout<<"加法结果是:"<<sum<<endl;
cout<<"请按任意键继续\n";
cout.flush();
cin.get();
cin.get();
}
void Sub() //减法函数
{
  user.nSub++;
  rational num1,num2,sub,Zero(0,0);
  cout<<"最少输入两个数,并且以-1结束\n";
  cout<<"第1个数:";
  cin>>num1;
  cout<<"第2个数:";
  cin>>num2;
  sub=num1-num2;
  cout<<"第3个数:";
  cin>>num1;
  int i=4;
   while(1)
{
sub=sub-num1;
cout<<"第"<<i<<"个数:";
cin>>num1;
i++;
if(num1==-1)
break;
}
cout<<"减法结果是:"<<sub<<endl;
cout<<"请按任意键继续\n";
cout.flush();
cin.get();
cin.get();
}
void Mul() //乘积函数
{
   user.nMul++;
   rational num1,num2,mul,Zero(0,0);
   cout<<"乘法计算\n"<<"最少输入两数,并且以-1结束\n";
   cout<<"第一个数:";
   cin>>num1;
   cout<<"第二个数:";
   cin>>num2;
   mul=num1*num2;
   cout<<"第三个数:";
   cin>>num1;
   int i=4;
  while(1)
  {
    num1=mul*num1;
    cout<<"第"<<i<<"个数:";
    cin>>num1;
    i++;
    if(num1==-1)
    break;
}
  cout<<"乘法结果是:"<<mul<<endl;
  cout<<"请按任意键继续\n";
  cout.flush();
  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.alAve<<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.nTest++;
        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));
    }
    cout << "欢迎您再次使用计算器!";
    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(-1 * (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;
}

int main(){
    rational t1,t2;
    rational c;
    int choise;
    Login(); //当前用户信息函数
    do
    {
        system("cls");
        cout << "\t这是一个简单的计算器程序,可以实现以下功能,请按对应的按键(1-5)\n\n\n";
        cout << "\t=========================MENU===========================\n";
        cout << "\t1:有理数加法,以0结束\n";
        cout << "\t2:有理数减法,以0结束\n";
        cout << "\t3:测试分数加减乘法运算,1次测试10道题\n";
        cout << "\t4:有理数乘法,以0结束\n";
        cout << "\t5:有理数除法,以0结束\n";
        cout << "\t0:退出程序\n\n:";
        cout << "\t请您选择:";
        cin >> choise;
        if (choise == 1)
        {   
            Add();
        }
        else if (choise == 2)
        {   
            Sub();
        }
        else if (choise == 3)
        {   
            Test();
        }
        else if (choise == 4)
        {   
            Mul();
        }
        else if (choise == 5)
        {   cin>>t1;
            cin>>t2;
            rational c = t1 / t2;
            c.optimization();    
            c.print();
        }
    
        else if (choise == 0) //用户选0则结束调用函数
        {
            cout << "\n\n\t欢迎下次继续使用计算器!\n";
            break;
        }
        else
        {
            cout << "\n\t输入错误,请按任意键继续!\n";
        }system("pause");
    } while (1);
    SaveFile(); //调用用户资料保存函数
    return 0;
}

img


谢谢大家!

  • 写回答

2条回答 默认 最新

  • 关注

    写法有问题,以Add函数和Sub函数为例,修改如下:

    void Add() //加法运算函数
    {
        user.nAdd++;
        rational num1,num2,sum,Zero(0,0);
        cout<<"加法计算\n"<<"最少输入两个数,并且以-1结束\n";
        int i=1;
        sum = 0;
        while(1)
        {
            cout<<"第"<<i<<"个数:";
            cin >> num1;
            if(num1==-1)
                break;
            sum=sum+num1;
            
            i++;
        }
        cout<<"加法结果是:"<<sum<<endl;
        cout<<"请按任意键继续\n";
        cout.flush();
        cin.get();
        cin.get();
    }
    
    
    void Sub() //减法函数
    {
        user.nSub++;
        rational num1,num2,sub,Zero(0,0);
        cout<<"最少输入两个数,并且以-1结束\n";
        cout<<"第1个数:";
        cin>>num1;
        sub = num1;
        int i=2;
        while(1)
        {
            cout<<"第"<<i<<"个数:";
            cin>>num1;
            if(num1==-1)
                break;
            sub=sub-num1;
            i++;
            
        }
        cout<<"减法结果是:"<<sub<<endl;
        cout<<"请按任意键继续\n";
        cout.flush();
        cin.get();
        cin.get();
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 4月6日
  • 已采纳回答 3月29日
  • 创建了问题 3月28日

悬赏问题

  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能
  • ¥15 jmeter脚本回放有的是对的有的是错的
  • ¥15 r语言蛋白组学相关问题