2015-02-24 4 views
0

У меня есть класс фракций, который позволяет вводить дробь в виде c/d. Я могу выводить и вводить фракции просто отлично, но когда я изменяю их с помощью своей пользовательской функции, показанной ниже, она ничего не делает.Двойная перегрузка операторов istream и ostream в C++

У меня есть следующий перегружена >> и < < операторов:

ostream& operator<<(ostream &out, const Fraction &f) 
{ 
    char x = '/'; 
    out << f.num; 
    out << x; 
    out << f.den; 
    return out; 
} 

istream& operator>>(istream &in, Fraction &r) 
{ 
    //in >> r; 
    int whole = 0, num, den = 1; 
    char next; 
    in >> num; 
    next = in.peek(); 
    if(next == '+'){ 
     in.get(); 
     whole = num; 
     in >> num; 
     next = in.peek(); 
    } 
    if(next == '/'){ 
     in.get(); 
     in >> den; 
    } 
    if(whole != 0){ 
     num += (whole * den); 
    } 
    if(den == 0){ 
     den = 1; 
    } 
    r.num = num; 
    r.den = den; 

    return in; 
} 

Кроме того, у меня есть функция, которая делает две фракции так, что они с таким же общим знаменателем:

void setEqualDen(Fraction a, Fraction b){ 
    int tempa = a.den; 
    int tempb = b.den; 
    a.den *= tempb; 
    b.den *= tempa; 
    a.num *= tempb; 
    b.num *= tempa; 
} 

Затем я попытаюсь вывести результат в основном так:

setEqualDen(Fa, Fb); 
    cout << "The fractions are " << Fa << " , " << Fb << 
      endl; 

Это не работает. Есть ли необходимый шаг, такой как двойная перегрузка операторов < < и >> на C++ или мой синтаксис просто что-то пропустил?

+2

Что вы подразумеваете под * не работает *? Если вы имеете в виду результат не то, что вы ожидаете, то это потому, что 'setEqualDen' делает копии своих аргументов вместо того, чтобы брать их по ссылке. Если это не проблема, объясните, что вы подразумеваете под двойной перегрузкой *, а также сообщения об ошибках, ожидаемом выходе и т. Д. – Praetorian

+0

Ваша входная функция не работает с этим текстом: «1 +/25». –

+0

Вместо того, чтобы предполагать количество пробелов, вы должны пропустить его. –

ответ

2

Вы хотите, чтобы & в определении функции, потому что вам нужно пройти по ссылке, так как вы изменяете свои «фракции».

void setEqualDen(Fraction &a, Fraction &b){ 
    int tempa = a.den; 
    int tempb = b.den; 
    a.den *= tempb; 
    b.den *= tempa; 
    a.num *= tempb; 
    b.num *= tempa; 
} 
+0

Это, вероятно, устранит проблему OP, но нет никакой причины, чтобы 'setEqualDen' был функцией-членом, поскольку он не обращается к экземпляру, на который он вызывается. – Praetorian

+0

Это дает мне ошибку при попытке вызвать функцию ... – JCoder

+0

@Praetorian - да, это хороший момент, который не нужен. Каково предпочтение здесь, поскольку функция действительна только для этого конкретного класса? Я бы сказал, сделайте его членом, чтобы вы могли перемещать класс и не волноваться о воссоздании функции в другой программе. – TriHard8

0

Необходимо проверить наличие ошибок ввода и пропустить пробелы. Я предлагаю использовать временную для первой цифры, поскольку это может быть либо целое число, либо числитель. Дифференциация должна произойти после обнаружения «/».

std::istream& operator>>(std::istream& inp, Fraction& f) 
{ 
    int temp = 0; 
    f.num = 0; 
    f.den = 1; 
    inp >> temp; // Could be whole number or numerator. 
    if (inp) 
    { 
    int whole = temp; 
    int numerator = 0; 
    inp >> numerator; 
    if (!inp) 
    { 
     // Let's assume that the input failed because of the '/' symbol. 
     numerator = temp; 
     whole = 0; 
     inp.clear(); 
    } 
    else 
    { 
     inp.ignore(1000, '/'); // Skip over the '/' 
    } 
    int denominator = 1; 
    inp >> denominator; 
    if (denominator == 0) denominator = 1; 
    numerator += whole * denominator; 
    f.num = numerator; 
    f.den = denominator; 
    } 
    return inp; 
} 
Смежные вопросы