繁体   English   中英

c++ 运行时错误代码(类/构造函数)

[英]c++ runtime error with code (classes/constructors)

我似乎遇到了两个错误:
A)循环的第一次迭代可以很好地打印出值,但是如果我在第 2 轮中按“y”到 go 它将自动填充第一个数字为“0/0”。 如图所示图片 B) 我想使用第三个构造函数来设置 numerator = num 和 denominator = den 但是,它似乎只是设置为默认值,所以我通过注释掉构造函数“Rational(num, den)”进行了临时修复并实际写了出分子= num; 和分母 = den;

任何帮助表示赞赏!

// Add appropriate headers

#include <iostream>
#include <cstdlib>
#include <string>
#include <cmath>
#include <sys/time.h>

using namespace std;

/*  KEEP THIS COMMENT
* class Rational
*    represents a Rational number. Remember rational means ratio-nal
*    which means there is a numerator and denominator having
*    integer values. Using good ADT techniques, we have made member
*    variable private (also known as instance variables) and made member
*    functions public.
*/
class Rational
{
private:   
 int numerator;
 int denominator;

 public:
    // ToDo: Default Constructor
    Rational();

    // ToDo: Constructor that takes int numerator
    Rational(int i);

    // ToDo: Constructor that takes int numerator and int denominator
    Rational(int p, int q);


    // ToDo: Member function to read a rational in the form: n/d
    void input();

    // ToDo: Member function to write a rational as n/d
    void output();

    // ToDo: declare an accessor function to get the numerator
    int getNumerator();

    // ToDo: declare an accessor function to get the denominator
    int getDenominator();

    // ToDo: delcare a function called Sum that takes two rational objects
    // sets the current object to the sum of the given objects using the
    // formula: a/b + c/d = ( a*d + b*c)/(b*d)
    void sum(Rational a, Rational b);

    // test if two rational numbers are equal.
    bool isEqual(const Rational& op);

};



int main()
{
    // ToDo: declare three rational objects using the default constructor
    Rational a, b, c;

    char answer='Y';

    // Main loop to read in rationals and compute the sum
    do {
        cout << "\nEnter op1 (in the format of p/q): ";
        a.input();
        //Debug line
        a.output();
        // ToDo: use your input member function to read the first rational

        cout << "\nEnter op2 (in the format of p/q): ";

        // ToDo: use your input member function to read the second rational
        b.input();
        //Debug line
        b.output();

        // ToDo: use the third rational to call Sum with first and second as parameters
        c.sum(a, b);

        cout << "\nThe sum of op1 and op2 is: ";
        c.output();
        // ToDo: ouptput the third rational

        cout << endl;

        cout << "\nTry again (Y/N)?";
        cin >> answer;

    } while (answer == 'y' || answer == 'Y');

    // ToDo: test getters 
    cout << "\nC's numerator is: " << c.getNumerator() << endl;
    cout << "\nC's denominator is: " << c.getDenominator() << endl;

    // TODO: Use two constructors to declare a whole number 3/1 and a 4/5

    // TODO: Use output to print both rationals
    //cout << .output() << " " << .output() << endl;


    return 0;
}

// ToDO: Implement your class member functions below.

Rational::Rational()
{
   numerator = 0;
   denominator = 1;
}

Rational::Rational(int i)
{
   numerator = i;
   denominator = 1;
}

Rational::Rational(int p, int q)
{
   numerator = p;
   denominator = q;
}

void Rational::sum(Rational a, Rational b)
{
   int num = (a.numerator*b.denominator + a.denominator*b.numerator);
   int den = (a.denominator*b.denominator);

   numerator = num;
   denominator = den;
}

void Rational::input()
{
   string in;
   int num,den;
   //cout << "Enter a rational number in the form of x/y : ";
   getline(cin, in);
   // find the index position of /
   int indx = in.find("/");
   // seperator out the numerator
   num = atoi(in.substr(0, indx).c_str());
   // seperate out the denominator
   den = atoi(in.substr(indx+1, in.length()).c_str());
   // Rational(num, den);

 //cout <<num << " " <<den << endl;   // Debug Line

 numerator = num;
 denominator = den;
 //cout <<numerator << " " <<denominator << endl;  // Debug Line 
}

void Rational::output()
{
   cout << numerator << "/" << denominator;
}

// Two getter functions
int Rational::getNumerator()
{
   return numerator;
}

这是解决方案。 如果您不知道 Buffer 是什么或者我们为什么要刷新它,请告诉我。 我将尝试进一步解释。

cout << "\nTry again (Y/N)?"; //In main
cin >> answer;
cin.ignore(256,'\n'); // Flush the buffer

这是解释。

是的,it(cin) 可以正常工作,因为 cin 对缓冲区没有任何问题。 但问题在于getline。 现在让我们解释一下原因。 首先,您需要知道计算机如何在程序中接受输入。 每当您输入一些值时,例如 cin>>x。 该值不会直接将 go 转换为 x。 首先,它存储在一些名为buffer的临时位置。 这就是您可以在控制台上按退格键的原因。 如果它直接写入更多变量(内存),则不能按退格键。 这意味着假设输入字符串你写了“appke”,但是你想写“apple”你可以按退格键(直到你没有按回车键)。 现在,当您输入输入并按 Enter 进行下一个输入时,您使用 cin 输入会发生什么。 就像在你的情况下你按下“y”然后输入(用“\n”表示)。 因此,当输入数据时,它会进入缓冲区,然后按 Enter 键,该输入也会进入缓冲区,但在您的情况下,系统只会从缓冲区中选择数据,例如“y”。 所以你的缓冲区仍然有来自以前数据的“\n”。 现在来getline。 它有一个名为“delim”的参数 [参见此处] http://www.cplusplus.com/reference/string/string/getline/告诉 getline 何时停止接受输入。 默认情况下,它的值为“\n”。 现在,从您之前的条目来看,您的缓冲区中已经有“\n”。 因此,当 getline 与缓冲区接触时,它会看到“\n”,并认为输入数据存在,因为他在缓冲区中找到“\n”,这是何时停止的指示符。 这就是为什么它没有要求输入。 现在来一个解决方案。 如果您认为在 cin 之后使用 getline。 您需要做的就是从缓冲区中删除“\n”。 所以你所做的就是 cin.ignore("\n")。 您要求 cin 忽略缓冲区中存在的“\n”。 所以当控制转到getline时。 它忽略缓冲区中已经存在的“\n”并正常工作。

您能否发布我遇到类似问题的最终程序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM