带有代码的C ++运行时错误(类/构造函数)

时间:2019-10-29 02:40:24

标签: c++ class

我似乎遇到了两个错误:
A)循环的第一次迭代可以很好地打印出值,但是,如果我按“ y”进入第2轮,它将自动将第一个数字填充为“ 0/0”。如图所示 Images B)我想使用第三个构造函数来设置分子= num和分母= 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;
}

1 个答案:

答案 0 :(得分:0)

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

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

这是解释。

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