C++输入操作符重载">>"

fpi*_*o07 6 c++ input operator-overloading cin rational-numbers

我有一个有理数的类是由两个整数组成的:num提名者和den分母.

以下运算符应该从流中读取有理数.

istream& operator >> (istream& Is, rational& r) {
  char c; //Test char.
   double n; //Could be either the numerator of the fraction or the antiperiod of the repeating decimal number.
    Is >> n;
    int i = 0;
    for (; n*10-pow(10, i+1) < 1 && int(n) != 0; i++) {
        n *= 10;
    }
    for (; int(n*10) % 10; i++) {
        n *= 10;
    }
    n /= pow(10, i);
    if (i == 0) {
        r.num = n;
        Is >> ws;
        c = Is.peek();
        if (c == '/') {
            c = Is.get();
            Is >> r.den;
        } else {
            r.den = 1;
        }
        r.normalize(); //This function normalizes the fraction.
    } else {
        Is >> ws;
        c = Is.peek();
        if (c == 'p' || c == 'P') {
            int p; //Period of the repeating decimal number.
            c = Is.get();
            Is >> p;
            vector<int> a = genFrac(n, p); //This function returns the fraction which express the decimal repeating number. It returns a "vector<int>" with the nominator at index 1 e denominator at index 0.
            r.num = a[1];
            r.den = a[0];
        } else {
            i = 0;
            for (; n*10-pow(10, i+1) < 1 && int(n) != 0; i++) {
                n *= 10;
            }
            for (; int(n*10) % 10 != 0; i++) {
                n *= 10;
            }
            int pot10 = pow(10, i);
            r.num = n;
            r.den = pot10;
        }
        r.normalize();
    }
    return Is;
}
Run Code Online (Sandbox Code Playgroud)

我写了这段代码来实现我的"理性"类的输入.我从我的C++书中编写的那个修改它,以便输入十进制数,包括重复数.

它应该能够处理这些类型的输入:

  • 9/8
  • 9
  • 9.87
  • 1.p3(= 1.3333333333)

但它不起作用,甚至不是我从书中复制的部分.

谁能帮我?

Jer*_*fin 5

我想我的写法有所不同1.

除非你真的需要这样做,否则我首先要阅读整个输入的"大块"(即所有字符到下一个空白区域),然后理清它应该如何表示一个数字,然后单独调用每种可能的表示的功能:

std::istream &operator>>(std::istream &is, rational &r) {
    std::string temp;

    Is >> temp;
    if (temp.find('/') != std::string::npos)
        r = cvt_fraction(temp, Is);
    else if (temp.find_first_of("pP") != std::string::npos)
        r = cvt_repeating(temp, Is);
    else if (temp.find('.') != std::string::npos)
        r = cvt_float(temp, Is);
    else
        r = cvt_int(temp, Is);
    return Is;
}
Run Code Online (Sandbox Code Playgroud)

我已经将istream传递给每个,原因有二:首先,如果他们在输入中发现垃圾,他们可以设置流的失败位.其次,如果他们真的需要阅读更多的输入,他们可以(但如果真的需要,我会有点惊讶).

在我看来,每个转换函数应该是相当微不足道的:如果我从字符串应该是digits "/" digits或"数字"p"数字" 的事实开始,进行转换通常会非常简单 - 具体来说很简单,我认为任何人都可以看一看代码并理清每件作品应该做什么.


  1. 老实说,我并不是故意讨厌,但如果我维护代码,然后遇到你的问题operator>>,我会有两种可能的反应之一:如果它显然有一个bug,请立即更换.否则,将其列入"技术债务"清单,并尽快更换.简单的事实是,就目前而言,需要进行大量的研究才能确定支持哪些输入格式,更不用说代码的哪个部分处理每个,或者整个事情应该如何处理共同努力,产生有意义的结果.